diff --git a/src/main/jastadd/Ros2Rag.relast b/src/main/jastadd/Ros2Rag.relast
index 166950375f5e56e0ade642999d02cd35d46e61fe..1008207a6ceb854a1937e7a2a16ef6e22cbccc03 100644
--- a/src/main/jastadd/Ros2Rag.relast
+++ b/src/main/jastadd/Ros2Rag.relast
@@ -11,11 +11,12 @@ ReadFromMqttDefinition : TokenUpdateDefinition;
 WriteToMqttDefinition  : TokenUpdateDefinition;
 
 // example: RobotArm._AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1
-DependencyDefinition ::= <ID> ;
-rel DependencyDefinition.Source -> TokenComponent ;
-rel DependencyDefinition.Target -> TokenComponent ;
+DependencyDefinition ::= <ID>;
+rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
+rel DependencyDefinition.Target -> TokenComponent;
 
 MappingDefinition ::= <ID> FromType:MappingDefinitionType <FromVariableName> ToType:MappingDefinitionType <Content> ;
 abstract MappingDefinitionType ::= ;
 JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
 JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
+DefaultMappingDefinition : MappingDefinition ;
diff --git a/src/main/jastadd/backend/Generation.jadd b/src/main/jastadd/backend/Generation.jadd
index c5f253f4a5a2c2d1d289512bd003927233eb790c..75be20c251f171af965eda685e00e489e3de023d 100644
--- a/src/main/jastadd/backend/Generation.jadd
+++ b/src/main/jastadd/backend/Generation.jadd
@@ -11,6 +11,8 @@ aspect GenerationUtils {
 }
 
 aspect AspectGeneration {
+  syn String TokenComponent.internalName() = getDependencySourceDefinitionList().isEmpty() ? externalName() : "_internal_" + getName();
+  syn String TokenComponent.externalName() = getName();
 
   // naming convention attributes
   syn String TokenUpdateDefinition.connectMethod() = "connect" + getToken().getName();
@@ -24,7 +26,7 @@ aspect AspectGeneration {
     Character.toUpperCase(getID().charAt(0)) +
     getID().substring(1);
   syn String DependencyDefinition.internalRelationPrefix() = "_internal_" + getID();
-  syn String DependencyDefinition.internalTokenName() = "_internal" + getSource().getName();
+  syn String DependencyDefinition.internalTokenName() = getSource().internalName();
 
   inh String UpdateDefinition.mqttUpdaterAttribute();
   inh String MappingDefinition.mqttUpdaterAttribute();
@@ -66,7 +68,7 @@ aspect AspectGeneration {
     sb.append(ind(1)).append("}\n\n");
 
     // mqttWaitUntilReady
-    sb.append(ind(1)).append("public void ").append(rootNodeName).append(".")
+    sb.append(ind(1)).append("public boolean ").append(rootNodeName).append(".")
       .append(mqttWaitUntilReadyMethod()).append("(long time, java.util.concurrent.TimeUnit unit) {\n");
     sb.append(ind(2)).append("return ").append(mqttUpdaterField()).append(".waitUntilReady(time, unit);\n");
     sb.append(ind(1)).append("}\n\n");
@@ -111,20 +113,32 @@ aspect AspectGeneration {
       String initialInputVariableName) {
     final String resultVariablePrefix = "result";  // we do not need "_" here, because methodName begins with one
     String inputVariableName = initialInputVariableName;
+    // last variable need to be declared before begin of try
+    MappingDefinition lastDefinition = getMappingList().get(getMappingList().size() - 1);
+    sb.append(ind(indent)).append(lastDefinition.getToType().prettyPrint()).append(" ")
+      .append(resultVariablePrefix).append(lastDefinition.methodName()).append(";\n");
+    sb.append(ind(indent)).append("try {\n");
     for (MappingDefinition mappingDefinition : getMappingList()) {
       String resultVariableName = resultVariablePrefix + mappingDefinition.methodName();
-      sb.append(ind(indent)).append(mappingDefinition.getToType().prettyPrint()).append(" ")
-        .append(resultVariablePrefix).append(mappingDefinition.methodName())
+      sb.append(ind(indent + 1));
+      if (mappingDefinition != lastDefinition) {
+        sb.append(mappingDefinition.getToType().prettyPrint()).append(" ");
+      }
+      sb.append(resultVariablePrefix).append(mappingDefinition.methodName())
         .append(" = ").append(mappingDefinition.methodName()).append("(")
         .append(inputVariableName).append(");\n");
       inputVariableName = resultVariableName;
     }
+    sb.append(ind(indent)).append("} catch (Exception e) {\n");
+    sb.append(ind(indent + 1)).append("e.printStackTrace();\n");
+    sb.append(ind(indent + 1)).append(preemptiveReturnStatement()).append("\n");
+    sb.append(ind(indent)).append("}\n");
     if (!getAlwaysApply()) {
-      sb.append(ind(indent)).append("if (get").append(getToken().getName()).append("()");
+      sb.append(ind(indent)).append("if (").append(preemptiveExpectedValue());
       if (getToken().isPrimitiveType()) {
         sb.append(" == ").append(inputVariableName);
       } else {
-        sb.append(" != null ? get").append(getToken().getName()).append("().equals(")
+        sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
           .append(inputVariableName).append(")").append(" : ")
           .append(inputVariableName).append(" == null");
       }
@@ -133,6 +147,10 @@ aspect AspectGeneration {
     return inputVariableName;
   }
 
+  syn String TokenUpdateDefinition.preemptiveExpectedValue();
+  eq ReadFromMqttDefinition.preemptiveExpectedValue() = "get" + getToken().getName() + "()";
+  eq WriteToMqttDefinition.preemptiveExpectedValue() = lastValue();
+
   syn String TokenUpdateDefinition.preemptiveReturnStatement();
   eq ReadFromMqttDefinition.preemptiveReturnStatement() = "return;";
   eq WriteToMqttDefinition.preemptiveReturnStatement() = "return false;";
@@ -188,7 +206,8 @@ aspect AspectGeneration {
   void MappingDefinition.generateAspect(StringBuilder sb) {
     sb.append(ind(1)).append("protected static ").append(getToType().prettyPrint())
       .append(" ASTNode.").append(methodName()).append("(")
-      .append(getFromType().prettyPrint()).append(" ").append(getFromVariableName()).append(") {\n");
+      .append(getFromType().prettyPrint()).append(" ").append(getFromVariableName())
+      .append(") throws Exception {\n");
     for (String line : getContent().split("\n")) {
       if (!line.trim().isEmpty()) {
         sb.append(ind(2)).append(line).append("\n");
@@ -226,7 +245,45 @@ aspect AspectGeneration {
     sb.append(ind(1)).append("public ");
     getSource().getJavaTypeUse().generateAbstractGrammar(sb);
     sb.append(" ").append(sourceParentTypeName).append(".get").append(getSource().getName()).append("() {\n");
-    sb.append(ind(2)).append("return get").append(internalTokenName()).append(";\n");
+    sb.append(ind(2)).append("return get").append(internalTokenName()).append("();\n");
     sb.append(ind(1)).append("}\n\n");
   }
 }
+
+aspect RelationGeneration {
+  syn java.util.List<Relation> Ros2Rag.additionalRelations() {
+    java.util.List<Relation> result = new java.util.ArrayList<>();
+    for (DependencyDefinition dd : getDependencyDefinitionList()) {
+      result.add(dd.getRelationToCreate());
+    }
+    return result;
+  }
+
+  syn nta Relation DependencyDefinition.getRelationToCreate() {
+    BidirectionalRelation result = new BidirectionalRelation();
+    NavigableRole left = new ListRole(internalRelationPrefix() + "Source");
+    left.setType(getTarget().containingTypeDecl());
+    NavigableRole right = new ListRole(internalRelationPrefix() + "Target");
+    right.setType(getSource().containingTypeDecl());
+    result.setLeft(left);
+    result.setRight(right);
+    return result;
+  }
+}
+
+aspect GrammarExtension {
+  refine BackendAbstractGrammar public void TokenComponent.generateAbstractGrammar(StringBuilder b) {
+    if (getNTA()) {
+      b.append("/");
+    }
+    b.append("<");
+    if (!getName().equals("")) {
+      b.append(internalName()).append(":");
+    }
+    getJavaTypeUse().generateAbstractGrammar(b);
+    b.append(">");
+    if (getNTA()) {
+      b.append("/");
+    }
+  }
+}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java b/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java
index a4f5bdc7f53251fecbd0aaf86d98faf017684259..7cd97a36113ca9af2566321f77b59e929f70b0cd 100644
--- a/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java
+++ b/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java
@@ -139,11 +139,12 @@ public class Compiler {
   private Ros2Rag parseProgram(String inputGrammarFileName, String inputRos2RagFileName) throws CompilerException {
     Program program = new Program();
     Ros2Rag ros2Rag;
+    GrammarFile inputGrammar;
 
     try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputGrammarFileName))) {
       Ros2RagScanner scanner = new Ros2RagScanner(reader);
       Ros2RagParser parser = new Ros2RagParser();
-      GrammarFile inputGrammar = (GrammarFile) parser.parse(scanner);
+      inputGrammar = (GrammarFile) parser.parse(scanner);
       inputGrammar.dumpTree(System.out);
       program.addGrammarFile(inputGrammar);
       inputGrammar.treeResolveAll();
@@ -159,11 +160,8 @@ public class Compiler {
     } catch (IOException | Parser.Exception e) {
       throw new CompilerException("Could not parse ros2rag file " + inputRos2RagFileName, e);
     }
-
-    ros2Rag.dumpTree(System.out);
     ros2Rag.treeResolveAll();
-    ros2Rag.dumpTree(System.out);
-
+    ros2Rag.additionalRelations().forEach(inputGrammar::addDeclaration);
     return ros2Rag;
   }
 
diff --git a/src/main/resources/MqttUpdater.jadd b/src/main/resources/MqttUpdater.jadd
index 53fa6cf5dacd874382416d2855eca9cbef225cd5..ef3e483fc80a389f4d5311cbfc6b9c0dccab7885 100644
--- a/src/main/resources/MqttUpdater.jadd
+++ b/src/main/resources/MqttUpdater.jadd
@@ -144,7 +144,7 @@ public class MqttUpdater {
     callbacks.put(topic, callback);
 
     // subscribe at broker
-    Topic[] topicArray = { new Topic(topic, this.qos) };
+    org.fusesource.mqtt.client.Topic[] topicArray = { new org.fusesource.mqtt.client.Topic(topic, this.qos) };
     connection.subscribe(topicArray, new org.fusesource.mqtt.client.Callback<byte[]>() {
       @Override
       public void onSuccess(byte[] qoses) {