diff --git a/ragconnect.base/src/main/jastadd/Analysis.jrag b/ragconnect.base/src/main/jastadd/Analysis.jrag
index 769d283301b8fb29064c8030bfee6f9fb5e433da..1fc2e2f44baccd87c861eaad699d739866a3aae0 100644
--- a/ragconnect.base/src/main/jastadd/Analysis.jrag
+++ b/ragconnect.base/src/main/jastadd/Analysis.jrag
@@ -24,44 +24,37 @@ aspect Analysis {
   }
 
   // --- isAlreadyDefined ---
-  syn boolean TokenEndpointDefinition.isAlreadyDefined() {
-    java.util.List<TokenEndpointDefinition> definitions = lookupTokenEndpointDefinitions(getToken());
-    java.util.Set<String> protocols = definitions
-      .stream()
-      .map(TokenEndpointDefinition::protocol)
-      .collect(java.util.stream.Collectors.toSet());
-    return definitions.size() > protocols.size();
-  }
+  syn boolean TokenEndpointDefinition.isAlreadyDefined() = lookupTokenEndpointDefinitions(getToken()).size() > 1;
   syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this;
 
-  // --- protocol ---
-  syn String TokenEndpointDefinition.protocol();
-  eq ReceiveFromMqttDefinition.protocol() = "mqtt";
-  eq SendToMqttDefinition.protocol() = "mqtt";
-  eq ReceiveFromRestDefinition.protocol() = "rest";
-  eq SendToRestDefinition.protocol() = "rest";
-
-  // --- usesPROTOCOL ---
-  syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty();
-  syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty();
+//  // --- protocol ---
+//  syn String TokenEndpointDefinition.protocol();
+//  eq ReceiveFromMqttDefinition.protocol() = "mqtt";
+//  eq SendToMqttDefinition.protocol() = "mqtt";
+//  eq ReceiveFromRestDefinition.protocol() = "rest";
+//  eq SendToRestDefinition.protocol() = "rest";
 
-  // --- mqttEndpointDefinitions ---
-  coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect;
-  ReceiveFromMqttDefinition contributes this
-    to RagConnect.mqttEndpointDefinitions()
-    for ragconnect();
-  SendToMqttDefinition contributes this
-    to RagConnect.mqttEndpointDefinitions()
-    for ragconnect();
+//  // --- usesPROTOCOL ---
+//  syn boolean RagConnect.usesMqtt() = !mqttEndpointDefinitions().isEmpty();
+//  syn boolean RagConnect.usesRest() = !restEndpointDefinitions().isEmpty();
 
-  // --- restEndpointDefinitions ---
-  coll java.util.List<TokenEndpointDefinition> RagConnect.restEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect;
-  ReceiveFromRestDefinition contributes this
-    to RagConnect.restEndpointDefinitions()
-    for ragconnect();
-  SendToRestDefinition contributes this
-    to RagConnect.restEndpointDefinitions()
-    for ragconnect();
+//  // --- mqttEndpointDefinitions ---
+//  coll java.util.List<TokenEndpointDefinition> RagConnect.mqttEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect;
+//  ReceiveFromMqttDefinition contributes this
+//    to RagConnect.mqttEndpointDefinitions()
+//    for ragconnect();
+//  SendToMqttDefinition contributes this
+//    to RagConnect.mqttEndpointDefinitions()
+//    for ragconnect();
+//
+//  // --- restEndpointDefinitions ---
+//  coll java.util.List<TokenEndpointDefinition> RagConnect.restEndpointDefinitions() [new java.util.ArrayList<>()] root RagConnect;
+//  ReceiveFromRestDefinition contributes this
+//    to RagConnect.restEndpointDefinitions()
+//    for ragconnect();
+//  SendToRestDefinition contributes this
+//    to RagConnect.restEndpointDefinitions()
+//    for ragconnect();
 
   syn boolean MappingDefinitionType.assignableTo(JavaTypeUse target);
   eq JavaMappingDefinitionType.assignableTo(JavaTypeUse target) = getType().assignableTo(target);
diff --git a/ragconnect.base/src/main/jastadd/MustacheNodes.relast b/ragconnect.base/src/main/jastadd/MustacheNodes.relast
index d2d611798005c45e810ebfeddfa6c767b36167e4..ceead524746145c07d1ea980bcd534e25979073b 100644
--- a/ragconnect.base/src/main/jastadd/MustacheNodes.relast
+++ b/ragconnect.base/src/main/jastadd/MustacheNodes.relast
@@ -1,7 +1,7 @@
 //TypeComponentMustache ;
 //rel TypeComponentMustache.TypeComponent -> TypeComponent ;
 
-MRagConnect ::= ReceiveDefinition:MReceiveDefinition* PushSendDefinition:MSendDefinition* PullSendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
+MRagConnect ::= ReceiveDefinition:MReceiveDefinition* SendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
 abstract MEndpointDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
 MReceiveDefinition : MEndpointDefinition;
 MSendDefinition : MEndpointDefinition;
diff --git a/ragconnect.base/src/main/jastadd/RagConnect.relast b/ragconnect.base/src/main/jastadd/RagConnect.relast
index 2729b85c23a87725a954e00d303caf1414cf9267..accc617714ff6bdd24a22831ea84e5d93e6a15b8 100644
--- a/ragconnect.base/src/main/jastadd/RagConnect.relast
+++ b/ragconnect.base/src/main/jastadd/RagConnect.relast
@@ -7,13 +7,8 @@ rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*;
 abstract TokenEndpointDefinition : EndpointDefinition;
 rel TokenEndpointDefinition.Token -> TokenComponent;
 
-abstract ReceiveTokenEndpointDefinition : TokenEndpointDefinition;
-abstract SendTokenEndpointDefinition : TokenEndpointDefinition;
-
-ReceiveFromMqttDefinition : ReceiveTokenEndpointDefinition;
-SendToMqttDefinition  : SendTokenEndpointDefinition;
-ReceiveFromRestDefinition : ReceiveTokenEndpointDefinition;
-SendToRestDefinition  : SendTokenEndpointDefinition;
+ReceiveTokenEndpointDefinition : TokenEndpointDefinition;
+SendTokenEndpointDefinition : TokenEndpointDefinition;
 
 DependencyDefinition ::= <ID>;
 rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
diff --git a/ragconnect.base/src/main/jastadd/backend/Configuration.jadd b/ragconnect.base/src/main/jastadd/backend/Configuration.jadd
index d4f5b43f27cb329f1ff82318c6f383f0f69ebbd6..8d3b16c3f99014408c6aefa5655201d222c3d892 100644
--- a/ragconnect.base/src/main/jastadd/backend/Configuration.jadd
+++ b/ragconnect.base/src/main/jastadd/backend/Configuration.jadd
@@ -2,4 +2,6 @@ aspect Configuration {
   public static boolean ASTNode.loggingEnabledForReads = false;
   public static boolean ASTNode.loggingEnabledForWrites = false;
   public static TypeDecl ASTNode.rootNode;
+  public static boolean ASTNode.usesMqtt;
+  public static boolean ASTNode.usesRest;
 }
diff --git a/ragconnect.base/src/main/jastadd/backend/Generation.jadd b/ragconnect.base/src/main/jastadd/backend/Generation.jadd
index ff948334b793fc4930585ee5705285187b7c2606..0bb7e85f7a8f3486c2dd1900e1c800d77aead1d1 100644
--- a/ragconnect.base/src/main/jastadd/backend/Generation.jadd
+++ b/ragconnect.base/src/main/jastadd/backend/Generation.jadd
@@ -34,25 +34,24 @@ aspect AttributesForMustache {
   eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField();
   eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0;
 
-  syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt();
+  syn String MRagConnect.closeMethod() = "ragconnectCloseConnections";
+//  syn boolean MRagConnect.usesMqtt() = getRagConnect().usesMqtt();
   syn String MRagConnect.mqttHandlerAttribute() = "_mqttHandler";
   syn String MRagConnect.mqttHandlerField() = "_mqttHandler";
-  syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost";
-  syn String MRagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady";
-  syn String MRagConnect.mqttCloseMethod() = "MqttCloseConnections";
+//  syn String MRagConnect.mqttSetHostMethod() = "MqttSetHost";
+  syn String MRagConnect.mqttSetupWaitUntilReadyMethod() = "ragconnectSetupMqttWaitUntilReady";
 
-  syn boolean MRagConnect.usesRest() = getRagConnect().usesRest();
+//  syn boolean MRagConnect.usesRest() = getRagConnect().usesRest();
   syn String MRagConnect.restHandlerAttribute() = "_restHandler";
   syn String MRagConnect.restHandlerField() = "_restHandler";
-  syn String MRagConnect.restSetPortMethod() = "RestSetPort";
-  syn String MRagConnect.restCloseMethod() = "RestCloseConnections";
+//  syn String MRagConnect.restSetPortMethod() = "RestSetPort";
 
   // --- MEndpointDefinition ---
   syn String MEndpointDefinition.preemptiveExpectedValue();
   syn String MEndpointDefinition.preemptiveReturn();
   syn TokenEndpointDefinition MEndpointDefinition.endpointDef();
   syn String MEndpointDefinition.firstInputVarName();
-  syn String MEndpointDefinition.newConnectionMethod();
+//  syn String MEndpointDefinition.newConnectionMethod();
 
   eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
   eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
@@ -61,21 +60,21 @@ aspect AttributesForMustache {
   inh String MEndpointDefinition.mqttHandlerAttribute();
   inh String MEndpointDefinition.restHandlerAttribute();
 
-  syn String MEndpointDefinition.connectParameterName() {
-    switch (endpointDef().protocol()) {
-      case "mqtt": return "topic";
-      case "rest": return "path";
-      default: return null;
-    }
-  }
-  syn String MEndpointDefinition.handlerAttribute() {
-    switch (endpointDef().protocol()) {
-      case "mqtt": return mqttHandlerAttribute();
-      case "rest": return restHandlerAttribute();
-      default: return null;
-    }
-  }
-  syn String MEndpointDefinition.connectMethod() = "connect" + tokenName() + (ragconnect().lookupTokenEndpointDefinitions(token()).size() > 1 ? "Via" + capitalize(endpointDef().protocol()) : "");
+  syn String MEndpointDefinition.connectParameterName() = "uriString";
+//    switch (endpointDef().protocol()) {
+//      case "mqtt": return "topic";
+//      case "rest": return "path";
+//      default: return null;
+//    }
+//  }
+//  syn String MEndpointDefinition.handlerAttribute() {
+//    switch (endpointDef().protocol()) {
+//      case "mqtt": return mqttHandlerAttribute();
+//      case "rest": return restHandlerAttribute();
+//      default: return null;
+//    }
+//  }
+  syn String MEndpointDefinition.connectMethod() = "connect" + tokenName();
   syn TokenComponent MEndpointDefinition.token() = endpointDef().getToken();
   syn boolean MEndpointDefinition.alwaysApply() = endpointDef().getAlwaysApply();
   syn String MEndpointDefinition.resultVarPrefix() = "result";  // we do not need "_" here, because methodName begins with one
@@ -112,39 +111,39 @@ aspect AttributesForMustache {
   eq MReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition();
   eq MReceiveDefinition.firstInputVarName() = "message";
 
-  syn String MReceiveDefinition.newConnectionMethod() {
-    switch (endpointDef().protocol()) {
-      case "mqtt": return "newConnection";
-      case "rest": return "newPUTConnection";
-      default: return null;
-    }
-  }
+//  syn String MReceiveDefinition.newConnectionMethod() {
+//    switch (endpointDef().protocol()) {
+//      case "mqtt": return "newConnection";
+//      case "rest": return "newPUTConnection";
+//      default: return null;
+//    }
+//  }
 
   // --- MSendDefinition ---
   eq MSendDefinition.preemptiveExpectedValue() = lastValue();
-  eq MSendDefinition.preemptiveReturn() {
-    switch (endpointDef().protocol()) {
-      case "mqtt": return "return false;";
-      case "rest": return "throw e;";  // e is Exception variable
-      default: return null;
-    }
-  }
+  eq MSendDefinition.preemptiveReturn() = "return false;";
+//    switch (endpointDef().protocol()) {
+//      case "mqtt": return "return false;";
+//      case "rest": return "throw e;";  // e is Exception variable
+//      default: return null;
+//    }
+//  }
   eq MSendDefinition.endpointDef() = getSendTokenEndpointDefinition();
   eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()";
 
-  syn String MSendDefinition.sendTopic() = "_topic_" + tokenName();
+  syn String MSendDefinition.sender() = "_sender_" + tokenName();
   syn String MSendDefinition.lastValue() = "_lastValue" + tokenName();
   syn String MSendDefinition.updateMethod() = "_update_" + tokenName();
   syn String MSendDefinition.writeMethod() = "_writeLastValue_" + tokenName();
   syn String MSendDefinition.tokenResetMethod() = "get" + tokenName() + "_reset";
-  syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush();
-  syn String MSendDefinition.newConnectionMethod() {
-    switch (endpointDef().protocol()) {
-      case "mqtt": return null;
-      case "rest": return "newGETConnection";
-      default: return null;
-    }
-  }
+//  syn boolean MSendDefinition.isPush() = getSendTokenEndpointDefinition().isPush();
+//  syn String MSendDefinition.newConnectionMethod() {
+//    switch (endpointDef().protocol()) {
+//      case "mqtt": return null;
+//      case "rest": return "newGETConnection";
+//      default: return null;
+//    }
+//  }
 
   // --- MMappingDefinition ---
   syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
@@ -182,11 +181,7 @@ aspect AttributesForMustache {
     for (EndpointDefinition def : getEndpointDefinitionList()) {
       if (def.isSendTokenEndpointDefinition()) {
         SendTokenEndpointDefinition sendDef = def.asSendTokenEndpointDefinition();
-        if (sendDef.isPush()) {
-          result.addPushSendDefinition(sendDef.toMustache());
-        } else {
-          result.addPullSendDefinition(sendDef.toMustache());
-        }
+        result.addSendDefinition(sendDef.toMustache());
       } else {
         result.addReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache());
       }
@@ -257,9 +252,9 @@ aspect AttributesForMustache {
 
 aspect AspectGeneration {
 
-  syn boolean SendTokenEndpointDefinition.isPush();
-  eq SendToMqttDefinition.isPush() = true;
-  eq SendToRestDefinition.isPush() = false;
+//  syn boolean SendTokenEndpointDefinition.isPush();
+//  eq SendToMqttDefinition.isPush() = true;
+//  eq SendToRestDefinition.isPush() = false;
 
   // --- rootNodeName ---
   syn String ASTNode.rootNodeName() = rootNode.getName();
diff --git a/ragconnect.base/src/main/jastadd/backend/Mappings.jrag b/ragconnect.base/src/main/jastadd/backend/Mappings.jrag
index 0410cc289d9e69fc27b343ac162cdd6b60bcb9d5..fb1239bfdd8e7ca0af60ea2382eff8dcfb22ed60 100644
--- a/ragconnect.base/src/main/jastadd/backend/Mappings.jrag
+++ b/ragconnect.base/src/main/jastadd/backend/Mappings.jrag
@@ -116,10 +116,8 @@ aspect Mappings {
 
   // --- isSuitableEdgeMapping(def) ---
   syn boolean TokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def);
-  eq ReceiveFromMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray();
-  eq SendToMqttDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray();
-  eq ReceiveFromRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isString();
-  eq SendToRestDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isString();
+  eq ReceiveTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getFromType().isByteArray();
+  eq SendTokenEndpointDefinition.isSuitableEdgeMapping(MappingDefinition def) = def.getToType().isByteArray();
 
   // --- isPrimitiveType ---
   syn boolean TokenComponent.isPrimitiveType() = effectiveJavaTypeUse().isPrimitiveType();
@@ -145,9 +143,9 @@ aspect Mappings {
 
   // --- suitableDefaultMapping ---
   syn DefaultMappingDefinition EndpointDefinition.suitableDefaultMapping();
-  eq ReceiveFromMqttDefinition.suitableDefaultMapping() {
+  eq ReceiveTokenEndpointDefinition.suitableDefaultMapping() {
     String typeName = getMappingList().isEmpty() ?
-        getToken().getJavaTypeUse().getName() :
+        getToken().effectiveJavaTypeUse().getName() :
         getMappingList().get(0).getFromType().prettyPrint();
     switch(typeName) {
       case "int":
@@ -166,9 +164,9 @@ aspect Mappings {
       default: return null;
     }
   }
-  eq SendToMqttDefinition.suitableDefaultMapping() {
+  eq SendTokenEndpointDefinition.suitableDefaultMapping() {
     String typeName = getMappingList().isEmpty() ?
-        getToken().getJavaTypeUse().getName() :
+        getToken().effectiveJavaTypeUse().getName() :
         getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint();
     switch(typeName) {
       case "int":
@@ -187,54 +185,54 @@ aspect Mappings {
       default: return null;
     }
   }
-  eq ReceiveFromRestDefinition.suitableDefaultMapping() {
-    String typeName = getMappingList().isEmpty() ?
-        getToken().getJavaTypeUse().getName() :
-        getMappingList().get(0).getFromType().prettyPrint();
-    switch(typeName) {
-      case "int":
-      case "Integer": return ragconnect().defaultStringToIntMapping();
-      case "short":
-      case "Short": return ragconnect().defaultStringToShortMapping();
-      case "long":
-      case "Long": return ragconnect().defaultStringToLongMapping();
-      case "float":
-      case "Float": return ragconnect().defaultStringToFloatMapping();
-      case "double":
-      case "Double": return ragconnect().defaultStringToDoubleMapping();
-      case "char":
-      case "Character": return ragconnect().defaultStringToCharMapping();
-      default: return null;
-    }
-  }
-  eq SendToRestDefinition.suitableDefaultMapping() {
-    String typeName = getMappingList().isEmpty() ?
-        getToken().getJavaTypeUse().getName() :
-        getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint();
-    switch(typeName) {
-      case "int":
-      case "Integer": return ragconnect().defaultIntToStringMapping();
-      case "short":
-      case "Short": return ragconnect().defaultShortToStringMapping();
-      case "long":
-      case "Long": return ragconnect().defaultLongToStringMapping();
-      case "float":
-      case "Float": return ragconnect().defaultFloatToStringMapping();
-      case "double":
-      case "Double": return ragconnect().defaultDoubleToStringMapping();
-      case "char":
-      case "Character": return ragconnect().defaultCharToStringMapping();
-      default: return null;
-    }
-  }
+//  eq ReceiveFromRestDefinition.suitableDefaultMapping() {
+//    String typeName = getMappingList().isEmpty() ?
+//        getToken().getJavaTypeUse().getName() :
+//        getMappingList().get(0).getFromType().prettyPrint();
+//    switch(typeName) {
+//      case "int":
+//      case "Integer": return ragconnect().defaultStringToIntMapping();
+//      case "short":
+//      case "Short": return ragconnect().defaultStringToShortMapping();
+//      case "long":
+//      case "Long": return ragconnect().defaultStringToLongMapping();
+//      case "float":
+//      case "Float": return ragconnect().defaultStringToFloatMapping();
+//      case "double":
+//      case "Double": return ragconnect().defaultStringToDoubleMapping();
+//      case "char":
+//      case "Character": return ragconnect().defaultStringToCharMapping();
+//      default: return null;
+//    }
+//  }
+//  eq SendToRestDefinition.suitableDefaultMapping() {
+//    String typeName = getMappingList().isEmpty() ?
+//        getToken().getJavaTypeUse().getName() :
+//        getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint();
+//    switch(typeName) {
+//      case "int":
+//      case "Integer": return ragconnect().defaultIntToStringMapping();
+//      case "short":
+//      case "Short": return ragconnect().defaultShortToStringMapping();
+//      case "long":
+//      case "Long": return ragconnect().defaultLongToStringMapping();
+//      case "float":
+//      case "Float": return ragconnect().defaultFloatToStringMapping();
+//      case "double":
+//      case "Double": return ragconnect().defaultDoubleToStringMapping();
+//      case "char":
+//      case "Character": return ragconnect().defaultCharToStringMapping();
+//      default: return null;
+//    }
+//  }
 
   // --- isByteArray ---
   syn boolean MappingDefinitionType.isByteArray() = false;
   eq JavaArrayMappingDefinitionType.isByteArray() = getType().getName().equals("byte");
 
-  // --- isString ---
-  syn boolean MappingDefinitionType.isString() = false;
-  eq JavaMappingDefinitionType.isString() = getType().getName().equals("String");
+//  // --- isString ---
+//  syn boolean MappingDefinitionType.isString() = false;
+//  eq JavaMappingDefinitionType.isString() = getType().getName().equals("String");
 
   // --- allMappingDefinitions ---
   syn java.util.List<MappingDefinition> RagConnect.allMappingDefinitions() {
@@ -255,19 +253,19 @@ aspect Mappings {
     result.add(defaultDoubleToBytesMapping());
     result.add(defaultCharToBytesMapping());
     result.add(defaultStringToBytesMapping());
-    // string conversion
-    result.add(defaultStringToIntMapping());
-    result.add(defaultStringToShortMapping());
-    result.add(defaultStringToLongMapping());
-    result.add(defaultStringToFloatMapping());
-    result.add(defaultStringToDoubleMapping());
-    result.add(defaultStringToCharMapping());
-    result.add(defaultIntToStringMapping());
-    result.add(defaultShortToStringMapping());
-    result.add(defaultLongToStringMapping());
-    result.add(defaultFloatToStringMapping());
-    result.add(defaultDoubleToStringMapping());
-    result.add(defaultCharToStringMapping());
+//    // string conversion
+//    result.add(defaultStringToIntMapping());
+//    result.add(defaultStringToShortMapping());
+//    result.add(defaultStringToLongMapping());
+//    result.add(defaultStringToFloatMapping());
+//    result.add(defaultStringToDoubleMapping());
+//    result.add(defaultStringToCharMapping());
+//    result.add(defaultIntToStringMapping());
+//    result.add(defaultShortToStringMapping());
+//    result.add(defaultLongToStringMapping());
+//    result.add(defaultFloatToStringMapping());
+//    result.add(defaultDoubleToStringMapping());
+//    result.add(defaultCharToStringMapping());
     return result;
   }
 }
diff --git a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
index 56a8dc4cc7f3396e778a529e981c1aefb302e18b..0432b0df96c44060f6df1d6918a856f62810230d 100644
--- a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
+++ b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
@@ -31,12 +31,8 @@ EndpointDefinition endpoint_definition
 ;
 
 EndpointDefinition endpoint_definition_type
-  = RECEIVE token_ref           {: return new ReceiveFromMqttDefinition().setToken(token_ref); :}
-  | RECEIVE token_ref VIA MQTT  {: return new ReceiveFromMqttDefinition().setToken(token_ref); :}
-  | RECEIVE token_ref VIA REST  {: return enableAlwaysApply(new ReceiveFromRestDefinition()).setToken(token_ref); :}
-  | SEND token_ref              {: return new SendToMqttDefinition().setToken(token_ref); :}
-  | SEND token_ref VIA MQTT     {: return new SendToMqttDefinition().setToken(token_ref); :}
-  | SEND token_ref VIA REST     {: return enableAlwaysApply(new SendToRestDefinition()).setToken(token_ref); :}
+  = RECEIVE token_ref           {: return new ReceiveTokenEndpointDefinition().setToken(token_ref); :}
+  | SEND token_ref              {: return new SendTokenEndpointDefinition().setToken(token_ref); :}
 ;
 
 TokenComponent token_ref
diff --git a/ragconnect.base/src/main/jastadd/scanner/Keywords.flex b/ragconnect.base/src/main/jastadd/scanner/Keywords.flex
index fe8a8141140884f7c53295f76877dd277c41ac4c..5773118d8fda8ffdc536b504aa7056b8784ddfb3 100644
--- a/ragconnect.base/src/main/jastadd/scanner/Keywords.flex
+++ b/ragconnect.base/src/main/jastadd/scanner/Keywords.flex
@@ -5,6 +5,3 @@
 "maps"       { return sym(Terminals.MAPS); }
 "to"         { return sym(Terminals.TO); }
 "as"         { return sym(Terminals.AS); }
-"via"        { return sym(Terminals.VIA); }
-"mqtt"       { return sym(Terminals.MQTT); }
-"rest"       { return sym(Terminals.REST); }
diff --git a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
index 5160ab6611f8a8f177555e55e511153b95a9659b..d44ef9e590abd09d3c7d7026c3da2dfe5f29511b 100644
--- a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
+++ b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
@@ -20,10 +20,14 @@ public class Compiler extends AbstractCompiler {
 
 //  private ValueOption optionOutputDir;
   private ValueOption optionRootNode;
+  private ValueOption optionProtocols;
   private BooleanOption optionVerbose;
   private BooleanOption optionLogReads;
   private BooleanOption optionLogWrites;
 
+  private static final String OPTION_PROTOCOL_MQTT = "mqtt";
+  private static final String OPTION_PROTOCOL_REST = "rest";
+
   public Compiler() {
     super("ragconnect", true);
   }
@@ -61,10 +65,10 @@ public class Compiler extends AbstractCompiler {
 
     printMessage("Writing output files");
     final List<String> handlers = new ArrayList<>();
-    if (ragConnect.usesMqtt()) {
+    if (ASTNode.usesMqtt) {
       handlers.add("MqttHandler.jadd");
     }
-    if (ragConnect.usesRest()) {
+    if (ASTNode.usesRest) {
       handlers.add("RestHandler.jadd");
     }
     // copy handlers into outputDir
@@ -138,6 +142,12 @@ public class Compiler extends AbstractCompiler {
         new ValueOption("rootNode", "root node in the base grammar.")
         .acceptAnyValue()
         .needsValue(true));
+    optionProtocols = addOption(
+        new ValueOption("protocols", "Protocols to enable")
+        .acceptMultipleValues(true)
+        .addDefaultValue(OPTION_PROTOCOL_MQTT, "Enable MQTT")
+        .addAcceptedValue(OPTION_PROTOCOL_REST, "Enable REST")
+    );
     optionVerbose = addOption(
         new BooleanOption("verbose", "Print more messages while compiling.")
         .defaultValue(false));
@@ -181,6 +191,8 @@ public class Compiler extends AbstractCompiler {
     ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
     ASTNode.loggingEnabledForReads = optionLogReads.value();
     ASTNode.loggingEnabledForWrites = optionLogWrites.value();
+    ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT);
+    ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST);
     return ragConnect;
   }
 
diff --git a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java
deleted file mode 100644
index 9da13bf479b6fe16be8c935b06cf1e9ad3283308..0000000000000000000000000000000000000000
--- a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package org.jastadd.ragconnect.compiler;
-
-import beaver.Parser;
-import org.jastadd.ragconnect.ast.*;
-import org.jastadd.ragconnect.parser.RagConnectParser;
-import org.jastadd.ragconnect.scanner.RagConnectScanner;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-/**
- * Testing Ros2Rag without parser.
- *
- * @author rschoene - Initial contribution
- */
-public class SimpleMain {
-
-  // --- just testing byte[] conversion ---
-  public static void testing() {
-    System.out.println("---");
-    try {
-      Class<?> clazz = Class.forName("java.util.List");
-      System.out.println("clazz.getName() = " + clazz.getName());
-      System.out.println(Integer.class.isAssignableFrom(Integer.class));
-      System.out.println(new SimpleJavaTypeUse("int").assignableTo(new SimpleJavaTypeUse("Integer")));
-    } catch (ClassNotFoundException e) {
-      e.printStackTrace();
-    }
-    System.out.println("---");
-
-    byte[] bytes;
-    int i = 1;
-    double d = 2.3d;
-    float f = 4.2f;
-    short sh = 13;
-    long l = 7L;
-    String s = "Hello";
-    char c = 'a';
-
-    Integer ii = Integer.valueOf(1);
-    if (!ii.equals(i)) throw new AssertionError("Ints not equal");
-
-    // int to byte
-    ByteBuffer i2b = ByteBuffer.allocate(4);
-    i2b.putInt(i);
-    bytes = i2b.array();
-
-    // byte to int
-    ByteBuffer b2i = ByteBuffer.wrap(bytes);
-    int actual_i = b2i.getInt();
-    if (i != actual_i) throw new AssertionError("Ints not equal");
-
-    // double to byte
-    ByteBuffer d2b = ByteBuffer.allocate(8);
-    d2b.putDouble(d);
-    bytes = d2b.array();
-
-    // byte to double
-    ByteBuffer b2d = ByteBuffer.wrap(bytes);
-    double actual_d = b2d.getDouble();
-    if (d != actual_d) throw new AssertionError("Doubles not equal");
-
-    // float to byte
-    ByteBuffer f2b = ByteBuffer.allocate(4);
-    f2b.putFloat(f);
-    bytes = f2b.array();
-
-    // byte to float
-    ByteBuffer b2f = ByteBuffer.wrap(bytes);
-    float actual_f = b2f.getFloat();
-    if (f != actual_f) throw new AssertionError("Floats not equal");
-
-    // short to byte
-    ByteBuffer sh2b = ByteBuffer.allocate(2);
-    sh2b.putShort(sh);
-    bytes = sh2b.array();
-
-    // byte to short
-    ByteBuffer b2sh = ByteBuffer.wrap(bytes);
-    short actual_sh = b2sh.getShort();
-    if (sh != actual_sh) throw new AssertionError("Shorts not equal");
-
-    // long to byte
-    ByteBuffer l2b = ByteBuffer.allocate(8);
-    l2b.putLong(l);
-    bytes = l2b.array();
-
-    // byte to long
-    ByteBuffer b2l = ByteBuffer.wrap(bytes);
-    long actual_l = b2l.getLong();
-    if (l != actual_l) throw new AssertionError("Longs not equal");
-
-    // String to byte
-    bytes = s.getBytes();
-
-    // byte to String
-    String actual_s = new String(bytes);
-    if (!s.equals(actual_s)) throw new AssertionError("Strings not equal");
-
-    // char to byte
-    ByteBuffer c2b = ByteBuffer.allocate(2);
-    c2b.putChar(c);
-    bytes = c2b.array();
-
-    // byte to char
-    ByteBuffer b2c = ByteBuffer.wrap(bytes);
-    char actual_c = b2c.getChar();
-    if (c != actual_c) throw new AssertionError("Floats not equal");
-  }
-
-  public static void main(String[] args) {
-    testing();
-//    createManualAST();
-  }
-
-  private static void createManualAST() {
-    RagConnect model = new RagConnect();
-    Program program = parseProgram(Paths.get("ros2rag.starter","src", "main", "jastadd", "RobotModel.relast"));
-    model.setProgram(program);
-
-    MappingDefinition mappingDefinition = new MappingDefinition();
-    mappingDefinition.setID("PoseToPosition");
-    mappingDefinition.setFromType(makeMappingDefinitionType("int"));
-    mappingDefinition.setFromVariableName("x");
-    mappingDefinition.setToType(makeMappingDefinitionType("Position"));
-    mappingDefinition.setContent("      pose.position.x += sqrt(.5 * size.x)\n" +
-        "      MAP round(2)\n" +
-        "      x = x / 100\n" +
-        "      IGNORE_IF_SAME\n" +
-        "    ;");
-    model.addMappingDefinition(mappingDefinition);
-
-    ReceiveFromMqttDefinition receiveFromMqttDefinition = new ReceiveFromMqttDefinition();
-    receiveFromMqttDefinition.setAlwaysApply(false);
-    receiveFromMqttDefinition.setToken(TokenComponent.createRef("Link.CurrentPosition"));
-    receiveFromMqttDefinition.addMapping(mappingDefinition);
-    model.addEndpointDefinition(receiveFromMqttDefinition);
-
-    model.treeResolveAll();
-    for (ErrorMessage error : model.errors()) {
-      System.err.println(error);
-    }
-
-    System.out.println(model.generateAspect("Model"));
-  }
-
-  private static MappingDefinitionType makeMappingDefinitionType(String type) {
-    JavaMappingDefinitionType result = new JavaMappingDefinitionType();
-    result.setType(new SimpleJavaTypeUse(type));
-    return result;
-  }
-
-  private static Program parseProgram(Path path) {
-    try (BufferedReader reader = Files.newBufferedReader(path)) {
-      RagConnectScanner scanner = new RagConnectScanner(reader);
-      RagConnectParser parser = new RagConnectParser();
-      GrammarFile grammarFile = (GrammarFile) parser.parse(scanner);
-      Program program = new Program();
-      program.addGrammarFile(grammarFile);
-      return program;
-    } catch (IOException | Parser.Exception e) {
-      e.printStackTrace();
-    }
-    return null;
-  }
-}
diff --git a/ragconnect.base/src/main/resources/MqttHandler.jadd b/ragconnect.base/src/main/resources/MqttHandler.jadd
index 1161211ffb0b90eaf26c7d27d709d71f7a6369c8..6f40612520cfb97151600dff53c8e0d384ab441e 100644
--- a/ragconnect.base/src/main/resources/MqttHandler.jadd
+++ b/ragconnect.base/src/main/resources/MqttHandler.jadd
@@ -1,4 +1,73 @@
-aspect MqttHandler {
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;aspect MqttHandler {
+public class MqttServerHandler {
+  private final java.util.Map<String, MqttHandler> handlers = new java.util.HashMap<>();
+  private long time;
+  private java.util.concurrent.TimeUnit unit;
+  private String name;
+
+  public MqttServerHandler() {
+    this("RagConnect");
+  }
+
+  public MqttServerHandler(String name) {
+    this.name = name;
+    setupWaitUntilReady(1, TimeUnit.SECONDS);
+  }
+
+  public void setupWaitUntilReady(long time, java.util.concurrent.TimeUnit unit) {
+    this.time = time;
+    this.unit = unit;
+  }
+
+  public MqttHandler resolveHandler(java.net.URI uri) throws IOException {
+    MqttHandler handler = handlers.get(uri.getHost());
+    if (handler == null) {
+      // first connect to that server
+      handler = new MqttHandler();
+      if (uri.getPort() == -1) {
+        handler.setHost(uri.getHost());
+      } else {
+        handler.setHost(uri.getHost(), uri.getPort());
+      }
+      handlers.put(uri.getHost(), handler);
+    }
+    handler.waitUntilReady(this.time, this.unit);
+    return handler;
+  }
+
+  public boolean newConnection(java.net.URI uri, java.util.function.Consumer<byte[]> callback) throws IOException {
+    return resolveHandler(uri).newConnection(extractTopic(uri), callback);
+  }
+
+  public void publish(java.net.URI uri, byte[] bytes) throws IOException {
+    resolveHandler(uri).publish(extractTopic(uri), bytes);
+  }
+
+  public void publish(java.net.URI uri, byte[] bytes, boolean retain) throws IOException {
+    resolveHandler(uri).publish(extractTopic(uri), bytes, retain);
+  }
+
+  public void publish(java.net.URI uri, byte[] bytes,
+                      org.fusesource.mqtt.client.QoS qos, boolean retain) throws IOException {
+    resolveHandler(uri).publish(extractTopic(uri), bytes, qos, retain);
+  }
+
+  private String extractTopic(java.net.URI uri) {
+    String path = uri.getPath();
+    if (path.charAt(0) == '/') {
+      path = path.substring(1);
+    }
+    return path;
+  }
+
+  public void close() {
+    for (MqttHandler handler : handlers.values()) {
+      handler.close();
+    }
+  }
+
+}
 /**
  * Helper class to receive updates via MQTT and use callbacks to handle those messages.
  *
@@ -14,10 +83,8 @@ public class MqttHandler {
   private java.net.URI host;
   /** The connection to the MQTT broker. */
   private org.fusesource.mqtt.client.CallbackConnection connection;
-  /** Whether we are subscribed to the topics yet */
-  private final java.util.concurrent.locks.Condition readyCondition;
-  private final java.util.concurrent.locks.Lock readyLock;
-  private boolean ready;
+  /** Whether we are connected yet */
+  private final java.util.concurrent.CountDownLatch readyLatch;
   private boolean sendWelcomeMessage = true;
   private org.fusesource.mqtt.client.QoS qos;
   /** Dispatch knowledge */
@@ -31,9 +98,7 @@ public class MqttHandler {
     this.name = java.util.Objects.requireNonNull(name, "Name must be set");
     this.logger = org.apache.logging.log4j.LogManager.getLogger(MqttHandler.class);
     this.callbacks = new java.util.HashMap<>();
-    this.readyLock = new java.util.concurrent.locks.ReentrantLock();
-    this.readyCondition = readyLock.newCondition();
-    this.ready = false;
+    this.readyLatch = new java.util.concurrent.CountDownLatch(1);
     this.qos = org.fusesource.mqtt.client.QoS.AT_LEAST_ONCE;
   }
 
@@ -144,13 +209,7 @@ public class MqttHandler {
   }
 
   private void setReady() {
-    try {
-      readyLock.lock();
-      ready = true;
-      readyCondition.signalAll();
-    } finally {
-      readyLock.unlock();
-    }
+    readyLatch.countDown();
   }
 
   private void throwIf(java.util.concurrent.atomic.AtomicReference<Throwable> error) throws java.io.IOException {
@@ -163,12 +222,15 @@ public class MqttHandler {
     this.qos = qos;
   }
 
-  public void newConnection(String topic, java.util.function.Consumer<byte[]> callback) {
-    if (!ready) {
-      // should maybe be something more kind than throwing an exception here
-      throw new IllegalStateException("Updater not ready");
+  public boolean newConnection(String topic, java.util.function.Consumer<byte[]> callback) {
+    if (readyLatch.getCount() > 0) {
+      System.err.println("Handler not ready");
+      return false;
+//      // should maybe be something more kind than throwing an exception here
+//      throw new IllegalStateException("Updater not ready");
     }
     // register callback
+    logger.debug("new connection for {}", topic);
     if (callbacks.get(topic) == null) {
       callbacks.put(topic, new java.util.ArrayList<>());
 
@@ -189,6 +251,7 @@ public class MqttHandler {
       });
     }
     callbacks.get(topic).add(callback);
+    return true;
   }
 
   /**
@@ -202,15 +265,9 @@ public class MqttHandler {
    */
   public boolean waitUntilReady(long time, java.util.concurrent.TimeUnit unit) {
     try {
-      readyLock.lock();
-      if (ready) {
-        return true;
-      }
-      return readyCondition.await(time, unit);
+      return readyLatch.await(time, unit);
     } catch (InterruptedException e) {
       e.printStackTrace();
-    } finally {
-      readyLock.unlock();
     }
     return false;
   }
@@ -253,7 +310,7 @@ public class MqttHandler {
 
         @Override
         public void onFailure(Throwable value) {
-          logger.warn("Could not publish on topic '{}'", topic);
+          logger.warn("Could not publish on topic '{}'", topic, value);
         }
       });
     });
diff --git a/ragconnect.base/src/main/resources/RestHandler.jadd b/ragconnect.base/src/main/resources/RestHandler.jadd
index 24118f04c563fe0b44105bfe674e269c76e7466f..f7b1a83304fe7aaebe97d105514c3f192d052aec 100644
--- a/ragconnect.base/src/main/resources/RestHandler.jadd
+++ b/ragconnect.base/src/main/resources/RestHandler.jadd
@@ -1,4 +1,45 @@
-aspect RestHandler {
+import java.util.concurrent.TimeUnit;aspect RestHandler {
+public class RestServerHandler {
+  private static final int DEFAULT_PORT = 4567;
+  private final java.util.Map<Integer, RestHandler> handlers = new java.util.HashMap<>();
+  private String name;
+
+  public RestServerHandler() {
+    this("RagConnect");
+  }
+
+  public RestServerHandler(String name) {
+    this.name = name;
+  }
+
+  private RestHandler resolveHandler(java.net.URI uri) {
+    int port = uri.getPort() != -1 ? uri.getPort() : DEFAULT_PORT;
+    RestHandler handler = handlers.get(port);
+    if (handler == null) {
+      // first connect to that server
+      handler = new RestHandler();
+      handler.setPort(port);
+      handlers.put(port, handler);
+    }
+    return handler;
+  }
+
+  public boolean newPUTConnection(java.net.URI uri, java.util.function.Consumer<String> callback) {
+    resolveHandler(uri).newPUTConnection(uri.getPath(), callback);
+    return true;
+  }
+
+  public boolean newGETConnection(java.net.URI uri, SupplierWithException<String> supplier) {
+    resolveHandler(uri).newGETConnection(uri.getPath(), supplier);
+    return true;
+  }
+
+  public void close() {
+    for (RestHandler handler : handlers.values()) {
+      handler.close();
+    }
+  }
+}
 /**
  * Helper class to receive updates and publishes information via REST.
  * @author rschoene - Initial contribution
@@ -54,7 +95,7 @@ public class RestHandler {
         if (errors.isEmpty()) {
           return "OK";
         } else {
-          return makeError(response, 500, errors.stream().collect(java.util.stream.Collectors.joining("\n", "The folloing errors happened: [", "]")));
+          return makeError(response, 500, errors.stream().collect(java.util.stream.Collectors.joining("\n", "The following error(s) happened: [", "]")));
         }
       });
     }
@@ -79,7 +120,7 @@ public class RestHandler {
     return message;
   }
 
-  public void start() {
+  private void start() {
     logger.info("Starting REST server at {}", this.port);
     spark.Spark.port(this.port);
     spark.Spark.init();
diff --git a/ragconnect.base/src/main/resources/handleUri.mustache b/ragconnect.base/src/main/resources/handleUri.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a9187f8c610b258b9da28e86da818e13b57d29d5
--- /dev/null
+++ b/ragconnect.base/src/main/resources/handleUri.mustache
@@ -0,0 +1,11 @@
+    String scheme,host, path;
+    java.net.URI uri;
+    try {
+      uri = new java.net.URI({{connectParameterName}});
+      scheme = uri.getScheme();
+      host = uri.getHost();
+      path = uri.getPath();
+    } catch (java.net.URISyntaxException e) {
+      System.err.println(e.getMessage());  // Maybe re-throw error?
+      return false;
+    }
diff --git a/ragconnect.base/src/main/resources/handler.mustache b/ragconnect.base/src/main/resources/handler.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..e89c451007ff309a77297b9b66fe0e20dece73b8
--- /dev/null
+++ b/ragconnect.base/src/main/resources/handler.mustache
@@ -0,0 +1,7 @@
+aspect RagConnectHandler {
+interface RagConnectHandler<T> {
+  boolean connectReceive(String path, java.util.function.Consumer<T> callback);
+  boolean sendPush(String path, T value);
+  boolean connectSendPull(String path, SupplierWithException<T> supplier);
+}
+}
diff --git a/ragconnect.base/src/main/resources/mqtt.mustache b/ragconnect.base/src/main/resources/mqtt.mustache
index 95b253a9b4b4e46fda738a66499b8e2a7cc3707d..f10ae88139d958d2f4b0a8f4245b64b41e0f1003 100644
--- a/ragconnect.base/src/main/resources/mqtt.mustache
+++ b/ragconnect.base/src/main/resources/mqtt.mustache
@@ -1,26 +1,16 @@
 aspect MQTT {
   private String {{rootNodeName}}.MqttName() { return "RagConnectMQTT"; }
-  private MqttHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttHandler(MqttName());
-  public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host) throws java.io.IOException {
-    {{mqttHandlerField}}.setHost(host);
-  }
-  public void {{rootNodeName}}.{{mqttSetHostMethod}}(String host, int port) throws java.io.IOException {
-    {{mqttHandlerField}}.setHost(host, port);
-  }
-
-  public boolean {{rootNodeName}}.{{mqttWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) {
-    return {{mqttHandlerField}}.waitUntilReady(time, unit);
-  }
+  private MqttServerHandler {{rootNodeName}}.{{mqttHandlerField}} = new MqttServerHandler(MqttName());
 
-  public void {{rootNodeName}}.{{mqttCloseMethod}}() {
-    {{mqttHandlerField}}.close();
+  public void {{rootNodeName}}.{{mqttSetupWaitUntilReadyMethod}}(long time, java.util.concurrent.TimeUnit unit) {
+    {{mqttHandlerField}}.setupWaitUntilReady(time, unit);
   }
 
   {{#getRootTypeComponents}}
-  {{#first}}inh MqttHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}}
+  {{#first}}inh MqttServerHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}}
   eq {{rootNodeName}}.get{{name}}().{{mqttHandlerAttribute}}() = {{mqttHandlerField}};
   {{/getRootTypeComponents}}
   {{^getRootTypeComponents}}
-  syn MqttHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}};
+  syn MqttServerHandler {{rootNodeName}}.{{mqttHandlerAttribute}}() = {{mqttHandlerField}};
   {{/getRootTypeComponents}}
 }
diff --git a/ragconnect.base/src/main/resources/ragconnect.mustache b/ragconnect.base/src/main/resources/ragconnect.mustache
index 24e25418d07766f0ac881683080a622687ceff8e..5b12e3fae20555a7fe9055b226ca0cb96bcff8f5 100644
--- a/ragconnect.base/src/main/resources/ragconnect.mustache
+++ b/ragconnect.base/src/main/resources/ragconnect.mustache
@@ -1,21 +1,17 @@
-{{#usesMqtt}}
-  {{> mqtt}}
-{{/usesMqtt}}
-{{#usesRest}}
-  {{> rest}}
-{{/usesRest}}
+{{#usesMqtt}}{{> mqtt}}{{/usesMqtt}}
+{{#usesRest}}{{> rest}}{{/usesRest}}
 aspect ROS2RAG {
+  public void {{rootNodeName}}.{{closeMethod}}() {
+    {{#usesMqtt}}{{mqttHandlerField}}.close();{{/usesMqtt}}
+    {{#usesRest}}{{restHandlerField}}.close();{{/usesRest}}
+  }
   {{#ReceiveDefinitions}}
     {{> receiveDefinition}}
   {{/ReceiveDefinitions}}
 
-  {{#PushSendDefinitions}}
-    {{> sendDefinitionPush}}
-  {{/PushSendDefinitions}}
-
-  {{#PullSendDefinitions}}
-    {{> sendDefinitionPull}}
-  {{/PullSendDefinitions}}
+  {{#SendDefinitions}}
+    {{> sendDefinition}}
+  {{/SendDefinitions}}
 
   {{#MappingDefinitions}}
     {{> mappingDefinition}}
diff --git a/ragconnect.base/src/main/resources/receiveDefinition.mustache b/ragconnect.base/src/main/resources/receiveDefinition.mustache
index 31a08c737349b6c2d16f14a0fab50065d2c01a35..62e2bf6faf441fe7c6d700bb8b4daf6168196c3e 100644
--- a/ragconnect.base/src/main/resources/receiveDefinition.mustache
+++ b/ragconnect.base/src/main/resources/receiveDefinition.mustache
@@ -1,9 +1,23 @@
-  public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) {
-    {{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, message -> {
+  public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}) throws java.io.IOException {
+    {{>handleUri}}
+    java.util.function.Consumer<byte[]> consumer = message -> {
       {{> mappingApplication}}
       {{#loggingEnabledForReads}}
       System.out.println("[Receive] " + {{connectParameterName}} + " -> {{tokenName}} = " + {{lastResult}});
       {{/loggingEnabledForReads}}
       set{{tokenName}}({{lastResult}});
-    });
+    };
+    switch (scheme) {
+    {{#usesMqtt}}
+      case "mqtt": return {{mqttHandlerAttribute}}().newConnection(uri, consumer);
+    {{/usesMqtt}}
+    {{#usesRest}}
+      case "rest": return {{restHandlerAttribute}}().newPUTConnection(uri, input -> {
+        consumer.accept(input.getBytes());
+      });
+    {{/usesRest}}
+      default:
+        System.err.println("Unknown protocol '" + scheme + "'.");
+        return false;
+    }
   }
diff --git a/ragconnect.base/src/main/resources/rest.mustache b/ragconnect.base/src/main/resources/rest.mustache
index fb77601c38467e0f3f1bd1f01993db410670ce16..6bbde2be4d26e519635c85a6f39f9a18514bfb19 100644
--- a/ragconnect.base/src/main/resources/rest.mustache
+++ b/ragconnect.base/src/main/resources/rest.mustache
@@ -1,18 +1,12 @@
 aspect REST {
   private String {{rootNodeName}}.RestName() { return "RagConnectREST"; }
-  private RestHandler {{rootNodeName}}.{{restHandlerField}} = new RestHandler(RestName());
-  public void {{rootNodeName}}.{{restSetPortMethod}}(int port) {
-    {{restHandlerField}}.setPort(port);
-  }
-  public void {{rootNodeName}}.{{restCloseMethod}}() {
-    {{restHandlerField}}.close();
-  }
+  private RestServerHandler {{rootNodeName}}.{{restHandlerField}} = new RestServerHandler(RestName());
 
   {{#getRootTypeComponents}}
-  {{#first}}inh RestHandler ASTNode.{{restHandlerAttribute}}();{{/first}}
+  {{#first}}inh RestServerHandler ASTNode.{{restHandlerAttribute}}();{{/first}}
   eq {{rootNodeName}}.get{{name}}().{{restHandlerAttribute}}() = {{restHandlerField}};
   {{/getRootTypeComponents}}
   {{^getRootTypeComponents}}
-  syn RestHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}};
+  syn RestServerHandler {{rootNodeName}}.{{restHandlerAttribute}}() = {{restHandlerField}};
   {{/getRootTypeComponents}}
 }
diff --git a/ragconnect.base/src/main/resources/sendDefinition.mustache b/ragconnect.base/src/main/resources/sendDefinition.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..517baab18824ead12ebca5f1d22901b3a960b0ba
--- /dev/null
+++ b/ragconnect.base/src/main/resources/sendDefinition.mustache
@@ -0,0 +1,51 @@
+  private Runnable {{parentTypeName}}.{{sender}} = null;
+  private byte[] {{parentTypeName}}.{{lastValue}} = null;
+
+  public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) {
+    {{>handleUri}}
+    switch (scheme) {
+    {{#usesMqtt}}
+      case "mqtt":
+        // MqttHandler handler = {{mqttHandlerAttribute}}().resolveHandler(uri);{{!optimize later}}
+        {{sender}} = () -> {
+          {{#loggingEnabledForWrites}}
+          System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{connectParameterName}});
+          {{/loggingEnabledForWrites}}
+          try {
+            {{mqttHandlerAttribute}}().publish(uri, {{lastValue}});
+          } catch (java.io.IOException e) {
+            e.printStackTrace();
+          }
+        };
+        {{updateMethod}}();
+        if (writeCurrentValue) {
+          {{writeMethod}}();
+        }
+        break;
+    {{/usesMqtt}}
+    {{#usesRest}}
+      case "rest":
+        {{restHandlerAttribute}}().newGETConnection(uri, () -> {
+          {{updateMethod}}();
+          return new String({{lastValue}});
+        });
+        break;
+    {{/usesRest}}
+      default:
+        System.err.println("Unknown protocol '" + scheme + "'.");
+        return false;
+    }
+    return true;
+  }
+
+  protected boolean {{parentTypeName}}.{{updateMethod}}() {
+    {{tokenResetMethod}}();
+    {{> mappingApplication}}
+    {{lastValue}} = {{lastResult}};
+    // normally we would return true here. unless no connect method was called so far to initialize {{sender}} yet
+    return {{sender}} != null;
+  }
+
+  protected void {{parentTypeName}}.{{writeMethod}}() {
+    {{sender}}.run();
+  }
diff --git a/ragconnect.base/src/main/resources/sendDefinitionPull.mustache b/ragconnect.base/src/main/resources/sendDefinitionPull.mustache
deleted file mode 100644
index 598846d86f9fc67167de7896f42c30cd0cfc3360..0000000000000000000000000000000000000000
--- a/ragconnect.base/src/main/resources/sendDefinitionPull.mustache
+++ /dev/null
@@ -1,7 +0,0 @@
-  public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) {
-    {{handlerAttribute}}().{{newConnectionMethod}}({{connectParameterName}}, () -> {
-      {{tokenResetMethod}}();
-      {{> mappingApplication}}
-      return {{lastResult}};
-    });
-  }
diff --git a/ragconnect.base/src/main/resources/sendDefinitionPush.mustache b/ragconnect.base/src/main/resources/sendDefinitionPush.mustache
deleted file mode 100644
index 3f75b18274d687d306f7778f9846aeca592fa86f..0000000000000000000000000000000000000000
--- a/ragconnect.base/src/main/resources/sendDefinitionPush.mustache
+++ /dev/null
@@ -1,24 +0,0 @@
-  private String {{parentTypeName}}.{{sendTopic}} = null;
-  private byte[] {{parentTypeName}}.{{lastValue}} = null;
-
-  public void {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) {
-    {{sendTopic}} = {{connectParameterName}};
-    {{updateMethod}}();
-    if (writeCurrentValue) {
-      {{writeMethod}}();
-    }
-  }
-
-  protected boolean {{parentTypeName}}.{{updateMethod}}() {
-    {{tokenResetMethod}}();
-    {{> mappingApplication}}
-    {{lastValue}} = {{lastResult}};
-    return true;
-  }
-
-  protected void {{parentTypeName}}.{{writeMethod}}() {
-    {{#loggingEnabledForWrites}}
-    System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{sendTopic}});
-    {{/loggingEnabledForWrites}}
-    {{handlerAttribute}}().publish({{sendTopic}}, {{lastValue}});
-  }
diff --git a/ragconnect.base/src/main/resources/tokenComponent.mustache b/ragconnect.base/src/main/resources/tokenComponent.mustache
index 729f442aebfc67ee2bbf5e559a9946405a275260..7de943a37edd9358fec19e53575629a44e976cff 100644
--- a/ragconnect.base/src/main/resources/tokenComponent.mustache
+++ b/ragconnect.base/src/main/resources/tokenComponent.mustache
@@ -3,11 +3,11 @@
     {{#DependencyDefinitions}}
     for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) {
       {{#targetEndpointDefinition}}
-      {{#isPush}}
+      {{!#isPush}}
       if (target.{{updateMethod}}()) {
         target.{{writeMethod}}();
       }
-      {{/isPush}}
+      {{!/isPush}}
       {{/targetEndpointDefinition}}
     }
     {{/DependencyDefinitions}}
diff --git a/ragconnect.tests/build.gradle b/ragconnect.tests/build.gradle
index 96b3d74270fae3c825621c5e5d199b6559105510..d638ec5001a8a58505045e37e480ac7c5d08079d 100644
--- a/ragconnect.tests/build.gradle
+++ b/ragconnect.tests/build.gradle
@@ -67,11 +67,9 @@ relastTest {
     compilerLocation = '../libs/relast.jar'
 }
 
-sourceSets {
-    test {
-        java.srcDir "src/test/java-gen"
-    }
-}
+File genSrc = file("src/test/java-gen");
+sourceSets.test.java.srcDir genSrc
+idea.module.generatedSourceDirs += genSrc
 
 clean {
     delete 'src/test/02-after-ragconnect/*/', 'src/test/03-after-relast/*/', 'src/test/java-gen/*/'
@@ -249,6 +247,7 @@ task preprocessViaTest(type: JavaExec, group: 'verification') {
             'src/test/01-input/via/Test.relast',
             'src/test/01-input/via/Test.connect',
             '--rootNode=A', '--verbose',
+            '--protocols=mqtt,rest',
             '--logReads', '--logWrites'
 }
 
diff --git a/ragconnect.tests/src/test/01-input/via/Test.connect b/ragconnect.tests/src/test/01-input/via/Test.connect
index 938490169415b2ce8f3da325ae2a1c768030921f..e4d2862a651dd6e68f67d2a492b6105a15f0a77c 100644
--- a/ragconnect.tests/src/test/01-input/via/Test.connect
+++ b/ragconnect.tests/src/test/01-input/via/Test.connect
@@ -1,16 +1,15 @@
-receive A.Mqtt2MqttInput via mqtt using MarkMqttInput ;
-receive A.Rest2RestInput via rest using MarkRestInput ;
-receive A.Mqtt2RestInput via mqtt using MarkMqttInput ;
-receive A.Rest2MqttInput via rest using MarkRestInput ;
-receive A.Both2BothInput via mqtt using MarkMqttInput ;
-receive A.Both2BothInput via rest using MarkRestInput ;
+receive A.Mqtt2MqttInput using MarkMqttInput ;
+receive A.Rest2RestInput using MarkRestInput ;
+receive A.Mqtt2RestInput using MarkMqttInput ;
+receive A.Rest2MqttInput using MarkRestInput ;
+receive A.Both2BothInput ;
 
-send A.Mqtt2MqttOutput via mqtt using MarkMqttOutput ;
-send A.Rest2RestOutput via rest using MarkRestOutput ;
-send A.Mqtt2RestOutput via rest using MarkRestOutput ;
-send A.Rest2MqttOutput via mqtt using MarkMqttOutput ;
-send A.Both2RestOutput via rest using MarkRestOutput ;
-send A.Both2MqttOutput via mqtt using MarkMqttOutput ;
+send A.Mqtt2MqttOutput using MarkMqttOutput ;
+send A.Rest2RestOutput using MarkRestOutput ;
+send A.Mqtt2RestOutput using MarkRestOutput ;
+send A.Rest2MqttOutput using MarkMqttOutput ;
+send A.Both2RestOutput using MarkRestOutput ;
+send A.Both2MqttOutput using MarkMqttOutput ;
 
 A.Mqtt2MqttOutput canDependOn A.Mqtt2MqttInput as dependencyMqtt2Mqtt ;
 A.Rest2RestOutput canDependOn A.Rest2RestInput as dependencyRest2Rest ;
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java
index 8482c308f29b8381bc698efac91c69e2e94a8d9f..3746ceb3eaf8c83671747000e1fbf70ff37b9e96 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java
@@ -11,6 +11,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.concurrent.TimeUnit;
 
+import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -49,7 +50,7 @@ public class DefaultOnlyReadTest extends AbstractMqttTest {
       sender.close();
     }
     if (model != null) {
-      model.MqttCloseConnections();
+      model.ragconnectCloseConnections();
     }
   }
 
@@ -62,23 +63,21 @@ public class DefaultOnlyReadTest extends AbstractMqttTest {
   @Test
   public void communicate() throws IOException, InterruptedException {
     createModel();
-
-    model.MqttSetHost(TestUtils.getMqttHost());
-    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
-
-    integers.connectIntValue(TOPIC_NATIVE_INT);
-    integers.connectShortValue(TOPIC_NATIVE_SHORT);
-    integers.connectLongValue(TOPIC_NATIVE_LONG);
-    floats.connectFloatValue(TOPIC_NATIVE_FLOAT);
-    floats.connectDoubleValue(TOPIC_NATIVE_DOUBLE);
-    chars.connectCharValue(TOPIC_NATIVE_CHAR);
-    chars.connectStringValue(TOPIC_NATIVE_STRING);
-    allBoxed.connectIntValue(TOPIC_BOXED_INTEGER);
-    allBoxed.connectShortValue(TOPIC_BOXED_SHORT);
-    allBoxed.connectLongValue(TOPIC_BOXED_LONG);
-    allBoxed.connectFloatValue(TOPIC_BOXED_FLOAT);
-    allBoxed.connectDoubleValue(TOPIC_BOXED_DOUBLE);
-    allBoxed.connectCharValue(TOPIC_BOXED_CHARACTER);
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
+
+    integers.connectIntValue(mqttUri(TOPIC_NATIVE_INT));
+    integers.connectShortValue(mqttUri(TOPIC_NATIVE_SHORT));
+    integers.connectLongValue(mqttUri(TOPIC_NATIVE_LONG));
+    floats.connectFloatValue(mqttUri(TOPIC_NATIVE_FLOAT));
+    floats.connectDoubleValue(mqttUri(TOPIC_NATIVE_DOUBLE));
+    chars.connectCharValue(mqttUri(TOPIC_NATIVE_CHAR));
+    chars.connectStringValue(mqttUri(TOPIC_NATIVE_STRING));
+    allBoxed.connectIntValue(mqttUri(TOPIC_BOXED_INTEGER));
+    allBoxed.connectShortValue(mqttUri(TOPIC_BOXED_SHORT));
+    allBoxed.connectLongValue(mqttUri(TOPIC_BOXED_LONG));
+    allBoxed.connectFloatValue(mqttUri(TOPIC_BOXED_FLOAT));
+    allBoxed.connectDoubleValue(mqttUri(TOPIC_BOXED_DOUBLE));
+    allBoxed.connectCharValue(mqttUri(TOPIC_BOXED_CHARACTER));
 
     sender = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
     assertTrue(sender.waitUntilReady(2, TimeUnit.SECONDS));
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java
index 11fe3d9f240ea595d2c9c5825148c555272ba8cc..80bd95c603da385184927862b42a6f54b1d4f57e 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java
@@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
@@ -50,7 +51,7 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
       receiver.close();
     }
     if (model != null) {
-      model.MqttCloseConnections();
+      model.ragconnectCloseConnections();
     }
   }
 
@@ -129,8 +130,7 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
   }
 
   private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
-    model.MqttSetHost(TestUtils.getMqttHost());
-    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     receiver = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
     assertTrue(receiver.waitUntilReady(2, TimeUnit.SECONDS));
@@ -205,19 +205,19 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
       data.lastBoxedCharValue = java.nio.ByteBuffer.wrap(bytes).getChar();
     });
 
-    nativeIntegers.connectIntValue(TOPIC_NATIVE_INT, writeCurrentValue);
-    nativeIntegers.connectShortValue(TOPIC_NATIVE_SHORT, writeCurrentValue);
-    nativeIntegers.connectLongValue(TOPIC_NATIVE_LONG, writeCurrentValue);
-    nativeFloats.connectFloatValue(TOPIC_NATIVE_FLOAT, writeCurrentValue);
-    nativeFloats.connectDoubleValue(TOPIC_NATIVE_DOUBLE, writeCurrentValue);
-    nativeChars.connectCharValue(TOPIC_NATIVE_CHAR, writeCurrentValue);
-    nativeChars.connectStringValue(TOPIC_NATIVE_STRING, writeCurrentValue);
-    boxedIntegers.connectIntValue(TOPIC_BOXED_INTEGER, writeCurrentValue);
-    boxedIntegers.connectShortValue(TOPIC_BOXED_SHORT, writeCurrentValue);
-    boxedIntegers.connectLongValue(TOPIC_BOXED_LONG, writeCurrentValue);
-    boxedFloats.connectFloatValue(TOPIC_BOXED_FLOAT, writeCurrentValue);
-    boxedFloats.connectDoubleValue(TOPIC_BOXED_DOUBLE, writeCurrentValue);
-    boxedChars.connectCharValue(TOPIC_BOXED_CHARACTER, writeCurrentValue);
+    nativeIntegers.connectIntValue(mqttUri(TOPIC_NATIVE_INT), writeCurrentValue);
+    nativeIntegers.connectShortValue(mqttUri(TOPIC_NATIVE_SHORT), writeCurrentValue);
+    nativeIntegers.connectLongValue(mqttUri(TOPIC_NATIVE_LONG), writeCurrentValue);
+    nativeFloats.connectFloatValue(mqttUri(TOPIC_NATIVE_FLOAT), writeCurrentValue);
+    nativeFloats.connectDoubleValue(mqttUri(TOPIC_NATIVE_DOUBLE), writeCurrentValue);
+    nativeChars.connectCharValue(mqttUri(TOPIC_NATIVE_CHAR), writeCurrentValue);
+    nativeChars.connectStringValue(mqttUri(TOPIC_NATIVE_STRING), writeCurrentValue);
+    boxedIntegers.connectIntValue(mqttUri(TOPIC_BOXED_INTEGER), writeCurrentValue);
+    boxedIntegers.connectShortValue(mqttUri(TOPIC_BOXED_SHORT), writeCurrentValue);
+    boxedIntegers.connectLongValue(mqttUri(TOPIC_BOXED_LONG), writeCurrentValue);
+    boxedFloats.connectFloatValue(mqttUri(TOPIC_BOXED_FLOAT), writeCurrentValue);
+    boxedFloats.connectDoubleValue(mqttUri(TOPIC_BOXED_DOUBLE), writeCurrentValue);
+    boxedChars.connectCharValue(mqttUri(TOPIC_BOXED_CHARACTER), writeCurrentValue);
   }
 
   private void setData(String integerDriver, String floatDriver, String stringDriver) {
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java
index 1a58b683d55b0401485c85caca8105914e6cf67f..3d0706c075d8e4af3b3c5e5fa703f3885b80ddf3 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java
@@ -11,6 +11,7 @@ import robot.RobotStateOuterClass.RobotState;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
@@ -42,7 +43,7 @@ public class ExampleTest extends AbstractMqttTest {
       handler.close();
     }
     if (model != null) {
-      model.MqttCloseConnections();
+      model.ragconnectCloseConnections();
     }
   }
 
@@ -210,8 +211,7 @@ public class ExampleTest extends AbstractMqttTest {
   }
 
   private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
-    model.MqttSetHost(TestUtils.getMqttHost());
-    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
     assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
@@ -233,9 +233,9 @@ public class ExampleTest extends AbstractMqttTest {
       }
     });
 
-    robotArm.connectAppropriateSpeed(TOPIC_CONFIG, writeCurrentValue);
-    link1.connectCurrentPosition(TOPIC_JOINT1);
-    link2.connectCurrentPosition(TOPIC_JOINT2);
+    robotArm.connectAppropriateSpeed(mqttUri(TOPIC_CONFIG), writeCurrentValue);
+    link1.connectCurrentPosition(mqttUri(TOPIC_JOINT1));
+    link2.connectCurrentPosition(mqttUri(TOPIC_JOINT2));
   }
 
   private void createModel() {
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java
index 595976330654d05ae6e7a37dd8514fe901b9164f..5ede1e1896afadc70da7b868cf4272eafa250514 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java
@@ -7,6 +7,7 @@ import read1write2.ast.*;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -44,7 +45,7 @@ public class Read1Write2Test extends AbstractMqttTest {
       handler.close();
     }
     if (model != null) {
-      model.MqttCloseConnections();
+      model.ragconnectCloseConnections();
     }
   }
 
@@ -137,8 +138,7 @@ public class Read1Write2Test extends AbstractMqttTest {
   }
 
   private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
-    model.MqttSetHost(TestUtils.getMqttHost());
-    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
     assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
@@ -181,15 +181,15 @@ public class Read1Write2Test extends AbstractMqttTest {
       dataOther2.lastStringValue = new String(bytes);
     });
 
-    onSameNonterminal.connectInput(TOPIC_SAME_READ);
-    onSameNonterminal.connectOutInteger(TOPIC_SAME_WRITE_INT, writeCurrentValue);
-    onSameNonterminal.connectOutString(TOPIC_SAME_WRITE_STRING, writeCurrentValue);
+    onSameNonterminal.connectInput(mqttUri(TOPIC_SAME_READ));
+    onSameNonterminal.connectOutInteger(mqttUri(TOPIC_SAME_WRITE_INT), writeCurrentValue);
+    onSameNonterminal.connectOutString(mqttUri(TOPIC_SAME_WRITE_STRING), writeCurrentValue);
 
-    onDifferentNonterminal.connectInput(TOPIC_DIFFERENT_READ);
-    other1.connectOutInteger(TOPIC_DIFFERENT_WRITE1_INT, writeCurrentValue);
-    other1.connectOutString(TOPIC_DIFFERENT_WRITE1_STRING, writeCurrentValue);
-    other2.connectOutInteger(TOPIC_DIFFERENT_WRITE2_INT, writeCurrentValue);
-    other2.connectOutString(TOPIC_DIFFERENT_WRITE2_STRING, writeCurrentValue);
+    onDifferentNonterminal.connectInput(mqttUri(TOPIC_DIFFERENT_READ));
+    other1.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE1_INT), writeCurrentValue);
+    other1.connectOutString(mqttUri(TOPIC_DIFFERENT_WRITE1_STRING), writeCurrentValue);
+    other2.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE2_INT), writeCurrentValue);
+    other2.connectOutString(mqttUri(TOPIC_DIFFERENT_WRITE2_STRING), writeCurrentValue);
   }
 
   private void sendData(String inputSame, String inputDifferent) {
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java
index 5f61867b5a254a92090a4b6d502100a356f12ddd..9881eb7110f98a3bc36301f2f7a163c417e9a54e 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java
@@ -7,6 +7,7 @@ import read2write1.ast.*;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -43,7 +44,7 @@ public class Read2Write1Test extends AbstractMqttTest {
       handler.close();
     }
     if (model != null) {
-      model.MqttCloseConnections();
+      model.ragconnectCloseConnections();
     }
   }
 
@@ -146,8 +147,7 @@ public class Read2Write1Test extends AbstractMqttTest {
   }
 
   private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
-    model.MqttSetHost(TestUtils.getMqttHost());
-    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
     assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
@@ -178,14 +178,14 @@ public class Read2Write1Test extends AbstractMqttTest {
       dataOther2.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
     });
 
-    onSameNonterminal.connectInput1(TOPIC_SAME_READ1);
-    onSameNonterminal.connectInput2(TOPIC_SAME_READ2);
-    onSameNonterminal.connectOutInteger(TOPIC_SAME_WRITE_INT, writeCurrentValue);
+    onSameNonterminal.connectInput1(mqttUri(TOPIC_SAME_READ1));
+    onSameNonterminal.connectInput2(mqttUri(TOPIC_SAME_READ2));
+    onSameNonterminal.connectOutInteger(mqttUri(TOPIC_SAME_WRITE_INT), writeCurrentValue);
 
-    onDifferentNonterminal.connectInput1(TOPIC_DIFFERENT_READ1);
-    onDifferentNonterminal.connectInput2(TOPIC_DIFFERENT_READ2);
-    other1.connectOutInteger(TOPIC_DIFFERENT_WRITE1_INT, writeCurrentValue);
-    other2.connectOutInteger(TOPIC_DIFFERENT_WRITE2_INT, writeCurrentValue);
+    onDifferentNonterminal.connectInput1(mqttUri(TOPIC_DIFFERENT_READ1));
+    onDifferentNonterminal.connectInput2(mqttUri(TOPIC_DIFFERENT_READ2));
+    other1.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE1_INT), writeCurrentValue);
+    other2.connectOutInteger(mqttUri(TOPIC_DIFFERENT_WRITE2_INT), writeCurrentValue);
   }
 
   private void sendData(boolean useSameInput1, String inputSame,
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
index 38616caf60907ff0b17da55d420180f00f1a225c..26c32c5a438bf133d984efa31bde4b05b3b15af1 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
@@ -1,7 +1,11 @@
 package org.jastadd.ragconnect.tests;
 
+import org.junit.jupiter.api.Assertions;
+
 import java.io.File;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -26,6 +30,14 @@ public class TestUtils {
     }
   }
 
+  public static String mqttUri(String path) {
+    return "mqtt://" + getMqttHost() + "/" + path;
+  }
+
+  public static String restUri(String path, int port) {
+    return "rest://localhost:" + port + "/" + path;
+  }
+
   public static int getMqttDefaultPort() {
     return 1883;
   }
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java
index e42393d48cc37b58ad7897ea65bf796c83110e98..896b8711fee14bce4dcf8a12006ddb9e26a5791c 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java
@@ -14,6 +14,8 @@ import javax.ws.rs.core.MediaType;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.TestUtils.restUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -62,8 +64,7 @@ public class ViaTest extends AbstractMqttTest {
       handler.close();
     }
     if (model != null) {
-      model.MqttCloseConnections();
-      model.RestCloseConnections();
+      model.ragconnectCloseConnections();
     }
   }
 
@@ -95,8 +96,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-201-R2R-ToRest",
         "FromMqtt-301-M2R-ToRest",
         2, "FromRest-401-R2M-ToMqtt",
-        2, "FromMqtt-501-B2M-ToMqtt",
-        "FromMqtt-501-B2R-ToRest");
+        2, "501-B2M-ToMqtt",
+        "501-B2R-ToRest");
 
     // send value only for bothInput via REST
     sendDataForBoth("502", false);
@@ -107,8 +108,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-201-R2R-ToRest",
         "FromMqtt-301-M2R-ToRest",
         2, "FromRest-401-R2M-ToMqtt",
-        3, "FromRest-502-B2M-ToMqtt",
-        "FromRest-502-B2R-ToRest");
+        3, "502-B2M-ToMqtt",
+        "502-B2R-ToRest");
 
     // send same value only for bothInput via MQTT
     sendDataForBoth("502", true);
@@ -119,8 +120,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-201-R2R-ToRest",
         "FromMqtt-301-M2R-ToRest",
         2, "FromRest-401-R2M-ToMqtt",
-        4, "FromMqtt-502-B2M-ToMqtt",
-        "FromMqtt-502-B2R-ToRest");
+        3, "502-B2M-ToMqtt",
+        "502-B2R-ToRest");
 
     // send values for other things
     sendData("102", "202", "302", "402");
@@ -131,8 +132,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-202-R2R-ToRest",
         "FromMqtt-302-M2R-ToRest",
         3, "FromRest-402-R2M-ToMqtt",
-        4, "FromMqtt-502-B2M-ToMqtt",
-        "FromMqtt-502-B2R-ToRest");
+        3, "502-B2M-ToMqtt",
+        "502-B2R-ToRest");
 
     // send same values again for other things
     sendData("102", "202", "302", "402");
@@ -143,8 +144,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-202-R2R-ToRest",
         "FromMqtt-302-M2R-ToRest",
         3, "FromRest-402-R2M-ToMqtt",
-        4, "FromMqtt-502-B2M-ToMqtt",
-        "FromMqtt-502-B2R-ToRest");
+        3, "502-B2M-ToMqtt",
+        "502-B2R-ToRest");
   }
 
   @Test
@@ -170,8 +171,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-211-R2R-ToRest",
         "FromMqtt-311-M2R-ToRest",
         1, "FromRest-411-R2M-ToMqtt",
-        1, "FromMqtt-511-B2M-ToMqtt",
-        "FromMqtt-511-B2R-ToRest");
+        1, "511-B2M-ToMqtt",
+        "511-B2R-ToRest");
 
     // send value only for bothInput via REST
     sendDataForBoth("512", false);
@@ -182,8 +183,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-211-R2R-ToRest",
         "FromMqtt-311-M2R-ToRest",
         1, "FromRest-411-R2M-ToMqtt",
-        2, "FromRest-512-B2M-ToMqtt",
-        "FromRest-512-B2R-ToRest");
+        2, "512-B2M-ToMqtt",
+        "512-B2R-ToRest");
 
     // send same value only for bothInput via MQTT
     sendDataForBoth("512", true);
@@ -194,8 +195,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-211-R2R-ToRest",
         "FromMqtt-311-M2R-ToRest",
         1, "FromRest-411-R2M-ToMqtt",
-        3, "FromMqtt-512-B2M-ToMqtt",
-        "FromMqtt-512-B2R-ToRest");
+        2, "512-B2M-ToMqtt",
+        "512-B2R-ToRest");
 
     // send values for other things
     sendData("112", "212", "312", "412");
@@ -206,8 +207,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-212-R2R-ToRest",
         "FromMqtt-312-M2R-ToRest",
         2, "FromRest-412-R2M-ToMqtt",
-        3, "FromMqtt-512-B2M-ToMqtt",
-        "FromMqtt-512-B2R-ToRest");
+        2, "512-B2M-ToMqtt",
+        "512-B2R-ToRest");
 
     // send same values again for other things
     sendData("112", "212", "312", "412");
@@ -218,8 +219,8 @@ public class ViaTest extends AbstractMqttTest {
         "FromRest-212-R2R-ToRest",
         "FromMqtt-312-M2R-ToRest",
         2, "FromRest-412-R2M-ToMqtt",
-        3, "FromMqtt-512-B2M-ToMqtt",
-        "FromMqtt-512-B2R-ToRest");
+        2, "512-B2M-ToMqtt",
+        "512-B2R-ToRest");
   }
 
   private void sendData(String inputMqtt2Mqtt, String inputRest2Rest, String inputMqtt2Rest, String inputRest2Mqtt) {
@@ -269,9 +270,7 @@ public class ViaTest extends AbstractMqttTest {
   }
 
   private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
-    model.MqttSetHost(TestUtils.getMqttHost());
-    model.RestSetPort(REST_PORT);
-    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
     assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
@@ -308,18 +307,18 @@ public class ViaTest extends AbstractMqttTest {
     senderRest2Mqtt = client.target(REST_SERVER_BASE_URL + PATH_REST_2_MQTT_RECEIVE);
     senderBoth2Rest = client.target(REST_SERVER_BASE_URL + PATH_BOTH_REST_RECEIVE);
 
-    model.connectMqtt2MqttInput(TOPIC_MQTT_2_MQTT_RECEIVE);
-    model.connectMqtt2MqttOutput(TOPIC_MQTT_2_MQTT_SEND, writeCurrentValue);
-    model.connectMqtt2RestInput(TOPIC_MQTT_2_REST_RECEIVE);
-    model.connectMqtt2RestOutput(PATH_MQTT_2_REST_SEND, writeCurrentValue);
-    model.connectRest2MqttInput(PATH_REST_2_MQTT_RECEIVE);
-    model.connectRest2MqttOutput(TOPIC_REST_2_MQTT_SEND, writeCurrentValue);
-    model.connectRest2RestInput(PATH_REST_2_REST_RECEIVE);
-    model.connectRest2RestOutput(PATH_REST_2_REST_SEND, writeCurrentValue);
-    model.connectBoth2BothInputViaMqtt(TOPIC_BOTH_MQTT_RECEIVE);
-    model.connectBoth2BothInputViaRest(PATH_BOTH_REST_RECEIVE);
-    model.connectBoth2MqttOutput(TOPIC_BOTH_2_MQTT_SEND, writeCurrentValue);
-    model.connectBoth2RestOutput(PATH_BOTH_2_REST_SEND, writeCurrentValue);
+    model.connectMqtt2MqttInput(mqttUri(TOPIC_MQTT_2_MQTT_RECEIVE));
+    model.connectMqtt2MqttOutput(mqttUri(TOPIC_MQTT_2_MQTT_SEND), writeCurrentValue);
+    model.connectMqtt2RestInput(mqttUri(TOPIC_MQTT_2_REST_RECEIVE));
+    model.connectMqtt2RestOutput(restUri(PATH_MQTT_2_REST_SEND, REST_PORT), writeCurrentValue);
+    model.connectRest2MqttInput(restUri(PATH_REST_2_MQTT_RECEIVE, REST_PORT));
+    model.connectRest2MqttOutput(mqttUri(TOPIC_REST_2_MQTT_SEND), writeCurrentValue);
+    model.connectRest2RestInput(restUri(PATH_REST_2_REST_RECEIVE, REST_PORT));
+    model.connectRest2RestOutput(restUri(PATH_REST_2_REST_SEND, REST_PORT), writeCurrentValue);
+    model.connectBoth2BothInput(mqttUri(TOPIC_BOTH_MQTT_RECEIVE));
+    model.connectBoth2BothInput(restUri(PATH_BOTH_REST_RECEIVE, REST_PORT));
+    model.connectBoth2MqttOutput(mqttUri(TOPIC_BOTH_2_MQTT_SEND), writeCurrentValue);
+    model.connectBoth2RestOutput(restUri(PATH_BOTH_2_REST_SEND, REST_PORT), writeCurrentValue);
   }
 
   private static class ReceiverData {
diff --git a/ragconnect.tests/src/test/resources/log4j2.xml b/ragconnect.tests/src/test/resources/log4j2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4c0d4548c61b23abad6aabc6811e68cd8a928871
--- /dev/null
+++ b/ragconnect.tests/src/test/resources/log4j2.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="INFO">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="debug">
+            <AppenderRef ref="Console"/>
+        </Root>
+        <Logger name="org.eclipse.jetty" level="info" additivity="false">
+            <AppenderRef ref="Console"/>
+        </Logger>
+    </Loggers>
+</Configuration>
diff --git a/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java b/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java
index 7c6d930aefa358a24b53be7349e1d667fc681380..a7a910395550868efa893efbf8ade2057e7b7b61 100644
--- a/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java
+++ b/ros2rag.common/src/main/java/de/tudresden/inf/st/ros2rag/common/Util.java
@@ -32,7 +32,11 @@ public class Util {
     handler.setHost(hostAndPort.host, hostAndPort.port);
   }
 
-  public static void iterateLinks(HandleLink callback, ActualConfiguration config) {
+  public static String mqttUri(String topic, ActualConfiguration config) {
+    return "mqtt://" + config.server + "/" + topic;
+  }
+
+  public static void iterateLinks(HandleLink callback, ActualConfiguration config) throws IOException {
     for (Map.Entry<String, SortedMap<String, String>> dataRobot : config.parts.entrySet()) {
       String topicPrefix = dataRobot.getKey() + "/";
       for (Map.Entry<String, String> dataLink : dataRobot.getValue().entrySet()) {
@@ -69,6 +73,6 @@ public class Util {
 
   @FunctionalInterface
   public interface HandleLink {
-    void handle(boolean isEndEffector, String topic, String name);
+    void handle(boolean isEndEffector, String topic, String name) throws IOException;
   }
 }
diff --git a/ros2rag.goal/build.gradle b/ros2rag.goal/build.gradle
index 0c537c2ba4f8d5a5f92fc572249ddcb0afa94896..3bfe45ab6c9aef96b069ff56faf8c47597f11acf 100644
--- a/ros2rag.goal/build.gradle
+++ b/ros2rag.goal/build.gradle
@@ -18,7 +18,9 @@ configurations {
     baseRuntimeClasspath
 }
 
-sourceSets.main.java.srcDir "src/gen/java"
+File genSrc = file("src/gen/java");
+sourceSets.main.java.srcDir genSrc
+idea.module.generatedSourceDirs += genSrc
 
 dependencies {
     implementation project (':ragconnect.base')
diff --git a/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java b/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java
index fc04dc9aeda6cc79222f1042a2d583abeeb86c6d..5dad7c9a5ef62f291fd67967cb067b2597d6239a 100644
--- a/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java
+++ b/ros2rag.goal/src/main/java/de/tudresden/inf/st/ros2rag/goal/GoalMain.java
@@ -33,7 +33,6 @@ public class GoalMain {
     ActualConfiguration config = Util.parseConfig(configFile);
 
     model = new GoalModel();
-    Util.setMqttHost(model::MqttSetHost, config);
 
     for (DataWorkPose dataWorkPose : config.goal_poses) {
       WorkPose workPose = new WorkPose();
@@ -60,7 +59,7 @@ public class GoalMain {
     robotState.setLastUpdate(0);
     model.setRobotState(robotState);
 
-    model.MqttWaitUntilReady(2, TimeUnit.SECONDS);
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     logger.debug("Setting dependencies");
     /*
@@ -82,15 +81,15 @@ public class GoalMain {
      */
     Util.iterateLinks((isEndEffector, topic, name) -> {
       if (isEndEffector) {
-        robotState.connectCurrentPosition(topic);
-        robotState.connectLastUpdate(topic);
+        robotState.connectCurrentPosition(Util.mqttUri(topic, config));
+        robotState.connectLastUpdate(Util.mqttUri(topic, config));
       }
     }, config);
     // next position is not initialized, so don't send it
-    model.getWorkflow().connectNextTrajectory(config.topics.trajectory, false);
-    model.getWorkflow().connectCurrentStep(config.topics.nextStep);
+    model.getWorkflow().connectNextTrajectory(Util.mqttUri(config.topics.trajectory, config), false);
+    model.getWorkflow().connectCurrentStep(Util.mqttUri(config.topics.nextStep, config));
     // initial next step is sent, as soon as this is received, the workflow starts
-    model.getWorkflow().connectReadyForThisStep(config.topics.nextStep, true);
+    model.getWorkflow().connectReadyForThisStep(Util.mqttUri(config.topics.nextStep, config), true);
 
     logStatus("Start");
     CountDownLatch exitCondition = new CountDownLatch(1);
@@ -140,7 +139,7 @@ public class GoalMain {
   private void close() {
     logger.info("Exiting ...");
     mainHandler.close();
-    model.MqttCloseConnections();
+    model.ragconnectCloseConnections();
   }
 
   public static void main(String[] args) throws IOException, InterruptedException {
diff --git a/ros2rag.safety/build.gradle b/ros2rag.safety/build.gradle
index 30d6296bdc98ad7a87f3dedbb0739fe6074120d2..4bfec22f282ed5700cd4bf05edfd4791b0f4515a 100644
--- a/ros2rag.safety/build.gradle
+++ b/ros2rag.safety/build.gradle
@@ -18,7 +18,10 @@ configurations {
     baseRuntimeClasspath
 }
 
-sourceSets.main.java.srcDir "src/gen/java"
+
+File genSrc = file("src/gen/java");
+sourceSets.main.java.srcDir genSrc
+idea.module.generatedSourceDirs += genSrc
 
 dependencies {
     implementation project (':ragconnect.base')
diff --git a/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java b/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java
index 7627ac005d67c1332323f95866b5f55703cfb532..bf34044f5f194c7a20e600ecd33b02da5116449c 100644
--- a/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java
+++ b/ros2rag.safety/src/main/java/de/tudresden/inf/st/ros2rag/starter/StarterMain.java
@@ -29,7 +29,6 @@ public class StarterMain {
 
     ActualConfiguration config = Util.parseConfig(configFile);
     model = new Model();
-    Util.setMqttHost(model::MqttSetHost, config);
 
     ZoneModel zoneModel = new ZoneModel();
 
@@ -45,7 +44,7 @@ public class StarterMain {
     }
     zoneModel.addSafetyZone(safetyZone);
     model.setZoneModel(zoneModel);
-    model.MqttWaitUntilReady(2, TimeUnit.SECONDS);
+    model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
 
     RobotArm robotArm = new RobotArm();
     model.setRobotArm(robotArm);
@@ -63,10 +62,10 @@ public class StarterMain {
       link.setName(name);
       link.setCurrentPosition(IntPosition.of(0, 0, 0));
       link.containingRobotArm().addDependency1(link);
-      link.connectCurrentPosition(topic);
+      link.connectCurrentPosition(Util.mqttUri(topic, config));
     }, config);
 
-    robotArm.connectAppropriateSpeed(config.topics.robotConfig, true);
+    robotArm.connectAppropriateSpeed(Util.mqttUri(config.topics.robotConfig, config), true);
 
     logStatus("Start", robotArm);
     CountDownLatch exitCondition = new CountDownLatch(1);
@@ -102,7 +101,7 @@ public class StarterMain {
   private void close() {
     logger.info("Exiting ...");
     mainHandler.close();
-    model.MqttCloseConnections();
+    model.ragconnectCloseConnections();
   }
 
   public static void main(String[] args) throws IOException, InterruptedException {