diff --git a/build.gradle b/build.gradle
index dec769678645445543fb08103107e15ec46d2ca4..afb6ee8d3a48638ddfae7a382219ec9cd3077ce4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -74,12 +74,12 @@ task relast(type: JavaExec) {
 
     inputs.files file("../libs/relast.jar"),
             file("../relast.preprocessor/src/main/jastadd/RelAST.relast"),
-            file("src/main/jastadd/Ros2Rag.relast")
-            file("src/main/jastadd/MustacheNodes.relast")
+            file("./src/main/jastadd/Ros2Rag.relast")
+            file("./src/main/jastadd/MustacheNodes.relast")
     outputs.files file("./src/gen/jastadd/Ros2Rag.ast"),
-            file("src/gen/jastadd/Ros2Rag.jadd"),
-            file("src/gen/jastadd/Ros2RagRefResolver.jadd"),
-            file('src/gen/jastadd/Ros2RagResolverStubs.jrag')
+            file("./src/gen/jastadd/Ros2Rag.jadd"),
+            file("./src/gen/jastadd/Ros2RagRefResolver.jadd"),
+            file('./src/gen/jastadd/Ros2RagResolverStubs.jrag')
 }
 
 jastadd {
diff --git a/src/main/jastadd/MustacheNodes.relast b/src/main/jastadd/MustacheNodes.relast
index 87c4d35cd0883cd40a35b17ebb9eb8ce2ee1bd2a..d9181d0ca3d72c6b9597f2300bb3f10b0d2fa866 100644
--- a/src/main/jastadd/MustacheNodes.relast
+++ b/src/main/jastadd/MustacheNodes.relast
@@ -1,19 +1,22 @@
 //TypeComponentMustache ;
 //rel TypeComponentMustache.TypeComponent -> TypeComponent ;
 
-MRos2Rag ::= ReadDefinition:MReadDefinition* WriteDefinition:MWriteDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* TypeComponent:MTypeComponent*;
-MUpdateDefinition ::= <FirstInputVarName>;
+MRos2Rag ::= ReadDefinition:MReadDefinition* WriteDefinition:MWriteDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeChildren:MTypeComponent* TokenComponent:MTokenComponent*;
+abstract MUpdateDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
 MReadDefinition : MUpdateDefinition;
 MWriteDefinition : MUpdateDefinition;
 MMappingDefinition;
+MInnerMappingDefinition;
 MDependencyDefinition;
 MTypeComponent;
+MTokenComponent;
 
-MUpdateDefinition.InnerMappingDefinition* -> MInnerMappingDefinition;
-MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
-MReadDefinition.ReadFromMqttDefinition -> ReadFromMqttDefinition;
-MWriteDefinition.WriteToMqttDefinition -> WriteToMqttDefinition;
-MMappingDefinition.MappingDefinition -> MappingDefinition;
-MDependencyDefinition.DependencyDefinition -> DependencyDefinition;
-MTypeComponent.TypeComponent -> TypeComponent;
-MTypeComponent.DependencyDefinition* -> MDependencyDefinition;
+rel MRos2Rag.Ros2Rag -> Ros2Rag;
+rel MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
+rel MReadDefinition.ReadFromMqttDefinition -> ReadFromMqttDefinition;
+rel MWriteDefinition.WriteToMqttDefinition -> WriteToMqttDefinition;
+rel MMappingDefinition.MappingDefinition -> MappingDefinition;
+rel MDependencyDefinition.DependencyDefinition -> DependencyDefinition;
+rel MTypeComponent.TypeComponent -> TypeComponent;
+rel MTokenComponent.TokenComponent -> TokenComponent;
+rel MTokenComponent.DependencyDefinition* -> MDependencyDefinition;
diff --git a/src/main/jastadd/Navigation.jrag b/src/main/jastadd/Navigation.jrag
index e181bc92401ef3e8e098685ac6047dba88e46954..a4f21e6e8d79c549a63d54474792382457bf74fd 100644
--- a/src/main/jastadd/Navigation.jrag
+++ b/src/main/jastadd/Navigation.jrag
@@ -2,10 +2,12 @@ aspect Navigation {
 
   // --- program ---
   eq Ros2Rag.getChild().program() = getProgram();
+  eq MRos2Rag.getChild().program() = getRos2Rag().program();
 
   // --- ros2rag ---
   inh Ros2Rag ASTNode.ros2rag();
   eq Ros2Rag.getChild().ros2rag() = this;
+  eq MRos2Rag.getChild().ros2rag() = getRos2Rag();
 
   // --- containedFile (first equation should be in preprocessor) ---
   eq Program.getChild().containedFile() = null;
@@ -32,6 +34,7 @@ aspect Navigation {
   eq GrammarFile.getChild().containedFileName() = getFileName();
   eq Ros2Rag.getChild().containedFileName() = getFileName();
   eq Program.getChild().containedFileName() = null;
+  eq MRos2Rag.getChild().containedFileName() = null;
 
   // --- isTokenUpdateDefinition ---
   syn boolean UpdateDefinition.isTokenUpdateDefinition() = false;
diff --git a/src/main/jastadd/backend/Generation.jadd b/src/main/jastadd/backend/Generation.jadd
index 2f2ff547924d3464c170cd995e6b10ddffeba3e2..01cbb9a39e92ea4a68875d6c46a219be29ff340c 100644
--- a/src/main/jastadd/backend/Generation.jadd
+++ b/src/main/jastadd/backend/Generation.jadd
@@ -31,34 +31,36 @@ aspect AttributesForMustache {
   // --- MUpdateDefinition ---
   syn String MUpdateDefinition.preemptiveExpectedValue();
   syn String MUpdateDefinition.preemptiveReturn();
-  syn String MUpdateDefinition.mqttUpdaterAttribute();
-  syn UpdateDefinition MUpdateDefinition.updateDef();
+  syn TokenUpdateDefinition MUpdateDefinition.updateDef();
+  syn String MUpdateDefinition.firstInputVarName();
 
-  eq MUpdateDefinition.getMInnerMappingDefinition(int i).isLast() = i == numInnerMappingDefinition();
+  eq MUpdateDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition();
   eq MUpdateDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
-  eq MUpdateDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? getFirstInputVarName() : resultVarPrefix() + getMInnerMappingDefinition(i - 1).getMappingDefinition().methodName();
+  eq MUpdateDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : resultVarPrefix() + getInnerMappingDefinition(i - 1).getMappingDefinition().methodName();
+  eq MRos2Rag.getChild().mqttUpdaterField() = getRos2Rag().mqttUpdaterField();
 
+  syn String MUpdateDefinition.mqttUpdaterAttribute() = updateDef().mqttUpdaterAttribute();
   syn String MUpdateDefinition.connectMethod() = updateDef().connectMethod();
   syn TokenComponent MUpdateDefinition.token() = updateDef().getToken();
   syn boolean MUpdateDefinition.alwaysApply() = updateDef().getAlwaysApply();
   syn String MUpdateDefinition.resultVarPrefix() = "result";  // we do not need "_" here, because methodName begins with one
   syn String MUpdateDefinition.parentTypeName() = token().containingTypeDecl().getName();
-  syn String MUpdateDefinition.TokenName() = token().getName();
-  syn MInnerMappingDefinition MUpdateDefinition.lastDefinition() = getInnerMappingDefinition(numInnerMappingDefinition() - 1);
+  syn String MUpdateDefinition.tokenName() = token().getName();
+  syn MInnerMappingDefinition MUpdateDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
   syn String MUpdateDefinition.lastDefinitionType() = lastDefinition().ToType();
   syn String MUpdateDefinition.lastDefinitionName() = lastDefinition().methodName();
+  syn String MUpdateDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
   syn String MUpdateDefinition.condition() {
-    String lastVarName = resultVarPrefix() + lastDefinitionDefinitionName();
     if (lastDefinition().getMappingDefinition().getToType().isArray()) {
-      return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastVarName + ")";
+      return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
     }
     if (token().isPrimitiveType() && lastDefinition().getMappingDefinition().getToType().isPrimitiveType()) {
-      return preemptiveExpectedValue() + " == " + lastVarName;
+      return preemptiveExpectedValue() + " == " + lastResult();
     }
     if (lastDefinition().getMappingDefinition().isDefaultMappingDefinition()) {
-      return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastVarName ")";
+      return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
     }
-    return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastVarName ") : " + inputVariableName + " == null";
+    return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastResult() + ") : " + lastResult() + " == null";
   }
 
   // --- MInnerMappingDefinition ---
@@ -69,18 +71,16 @@ aspect AttributesForMustache {
   inh String MInnerMappingDefinition.inputVarName();
 
   // --- MReadDefinition ---
-  eq MReadDefinition.connectMethod() = getReadFromMqttDefinition().connectMethod();
-  eq MReadDefinition.preemptiveExpectedValue() = "get" + TokenName() + "()";
+  eq MReadDefinition.preemptiveExpectedValue() = "get" + tokenName() + "()";
   eq MReadDefinition.preemptiveReturn() = "return;";
   eq MReadDefinition.updateDef() = getReadFromMqttDefinition();
-
-  syn String MReadDefinition.mqttUpdaterAttribute() = getReadFromMqttDefinition().mqttUpdaterAttribute;
-  syn String MReadDefinition.lastResult() = getReadFromMqttDefinition();
+  eq MReadDefinition.firstInputVarName() = "message";
 
   // --- MWriteDefinition ---
   eq MWriteDefinition.preemptiveExpectedValue() = lastValue();
   eq MWriteDefinition.preemptiveReturn() = "return false;";
   eq MWriteDefinition.updateDef() = getWriteToMqttDefinition();
+  eq MWriteDefinition.firstInputVarName() = "get" + tokenName() + "()";
 
   syn String MWriteDefinition.writeTopic() = getWriteToMqttDefinition().writeTopic();
   syn String MWriteDefinition.lastValue() = getWriteToMqttDefinition().lastValue();
@@ -101,69 +101,88 @@ aspect AttributesForMustache {
   syn String MDependencyDefinition.sourceParentTypeName() = getDependencyDefinition().getSource().containingTypeDecl().getName();
   syn String MDependencyDefinition.internalRelationPrefix() = getDependencyDefinition().internalRelationPrefix();
   syn nta MUpdateDefinition MDependencyDefinition.targetUpdateDefinition() {
-    return wrap(getDependencyDefinition().targetUpdateDefinition());
+    return getDependencyDefinition().targetUpdateDefinition().toMustache();
   }
 
   // --- MTypeComponent ---
-  syn String MTypeComponent.parentTypeName() = getTypeComponent().containingTypeDecl().getName();
   syn String MTypeComponent.name() = getTypeComponent().getName();
-  syn String MTypeComponent.javaType() = getTypeComponent().getJavaTypeUse().prettyPrint();
-  syn String MTypeComponent.internalName() = getTypeComponent().internalName();
+  inh String MTypeComponent.mqttUpdaterAttribute();
+  inh String MTypeComponent.mqttUpdaterField();
+
+  // --- MTokenComponent ---
+  syn String MTokenComponent.parentTypeName() = getTokenComponent().containingTypeDecl().getName();
+  syn String MTokenComponent.name() = getTokenComponent().getName();
+  syn String MTokenComponent.javaType() = getTokenComponent().getJavaTypeUse().prettyPrint();
+  syn String MTokenComponent.internalName() = getTokenComponent().internalName();
 
-  // --- wrap ---
-  syn lazy MRos2Rag Ros2Rag.wrap() {
+  // --- toMustache ---
+  syn lazy MRos2Rag Ros2Rag.toMustache() {
     MRos2Rag result = new MRos2Rag();
+    result.setRos2Rag(this);
     for (UpdateDefinition def : getUpdateDefinitionList()) {
       if (def.isWriteToMqttDefinition()) {
-        result.addWriteDefinition(def.asWriteToMqttDefinition.wrap());
+        result.addWriteDefinition(def.asWriteToMqttDefinition().toMustache());
       } else {
-        result.addReadDefinition(def.asReadFromMqttDefinition().wrap());
+        result.addReadDefinition(def.asReadFromMqttDefinition().toMustache());
       }
     }
     for (MappingDefinition def : allMappingDefinitions()) {
-      result.addMappingDefinition(def.wrap());
+      result.addMappingDefinition(def.toMustache());
     }
     for (DependencyDefinition def : getDependencyDefinitionList()) {
-      result.addDependencyDefinition(def.wrap());
+      result.addDependencyDefinition(def.toMustache());
     }
     for (TokenComponent token : getProgram().allTokenComponents()) {
-      result.addTokenComponent(token.wrap());
+      result.addTokenComponent(token.toMustache());
+    }
+    for (Component child : rootNode.getComponentList()) {
+      if (child.isTypeComponent()) {
+        result.addRootTypeChildren(child.asTypeComponent().toMustache());
+      }
     }
     return result;
   }
+
 //MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
-  private void MUpdateDefinition.addInnerMappings() {
-    for (MappingDefinition def : updateDefinition().effectiveMappings()) {
-      addInnerMappingDefinition(def.wrap());
+  protected void MUpdateDefinition.addInnerMappings() {
+    for (MappingDefinition def : updateDef().effectiveMappings()) {
+      MInnerMappingDefinition inner = new MInnerMappingDefinition();
+      inner.setMappingDefinition(def);
+      addInnerMappingDefinition(inner);
     }
   }
-  syn lazy MReadDefinition ReadFromMqttDefinition.wrap() {
+  syn lazy MReadDefinition ReadFromMqttDefinition.toMustache() {
     MReadDefinition result = new MReadDefinition();
     result.setReadFromMqttDefinition(this);
     result.addInnerMappings();
     return result;
   }
-  syn lazy MWriteDefinition WriteToMqttDefinition.wrap() {
+  syn lazy MWriteDefinition WriteToMqttDefinition.toMustache() {
     MWriteDefinition result = new MWriteDefinition();
     result.setWriteToMqttDefinition(this);
     result.addInnerMappings();
     return result;
   }
-  syn lazy MMappingDefinition MappingDefinition.wrap() {
+  syn lazy MMappingDefinition MappingDefinition.toMustache() {
     MMappingDefinition result = new MMappingDefinition();
     result.setMappingDefinition(this);
     return result;
   }
-  syn lazy MDependencyDefinition DependencyDefinition.wrap() {
+  syn lazy MDependencyDefinition DependencyDefinition.toMustache() {
     MDependencyDefinition result = new MDependencyDefinition();
     result.setDependencyDefinition(this);
     return result;
   }
-  syn lazy MTypeComponent TypeComponent.wrap() {
+  syn lazy MTypeComponent TypeComponent.toMustache() {
     MTypeComponent result = new MTypeComponent();
     result.setTypeComponent(this);
+    return result;
+  }
+  syn lazy MTokenComponent TokenComponent.toMustache() {
+    MTokenComponent result = new MTokenComponent();
+    result.setTokenComponent(this);
     for (DependencyDefinition def : getDependencySourceDefinitionList()) {
-      result.addDependencyDefinition(def.wrap());
+      result.addDependencyDefinition(def.toMustache());
     }
     return result;
   }
@@ -202,239 +221,241 @@ aspect AspectGeneration {
   eq Ros2Rag.getChild().mqttUpdaterAttribute() = mqttUpdaterAttribute();
 
   // --- mqttUpdaterField ---
-  eq Ros2Rag.getChild().mqttUpdaterField() = mqttUpdaterField();
 
   // --- rootNodeName ---
   syn String ASTNode.rootNodeName() = rootNode.getName();
 
   // mustache specific nodes
-  syn nta TypeComponentMustache TypeComponent.mustache() {
-    TypeComponentMustache result = new TypeComponentMustache();
-    result.setTypeComponent(this);
-    return result;
-  }
-  syn String TypeComponentMustache.name() = getTypeComponent().getName();
-  inh String TypeComponentMustache.mqttUpdaterAttribute();
-  inh String TypeComponentMustache.mqttUpdaterField();
-
-  // mustache specific attributes
-  syn java.util.List<TypeComponentMustache> Ros2Rag.rootTypeChildren() {
-    java.util.List<TypeComponentMustache> result = new java.util.ArrayList<>();
-    for (Component child : rootNode.getComponentList()) {
-      if (child.isTypeComponent()){
-        result.add(child.asTypeComponent().mustache());
-      }
-    }
-    return result;
-  }
+//  syn nta TypeComponentMustache TypeComponent.mustache() {
+//    TypeComponentMustache result = new TypeComponentMustache();
+//    result.setTypeComponent(this);
+//    return result;
+//  }
+//  syn String TypeComponentMustache.name() = getTypeComponent().getName();
+//  inh String TypeComponentMustache.mqttUpdaterAttribute();
+//  inh String TypeComponentMustache.mqttUpdaterField();
+//
+//  // mustache specific attributes
+//  syn java.util.List<TypeComponentMustache> Ros2Rag.rootTypeChildren() {
+//    java.util.List<TypeComponentMustache> result = new java.util.ArrayList<>();
+//    for (Component child : rootNode.getComponentList()) {
+//      if (child.isTypeComponent()){
+//        result.add(child.asTypeComponent().mustache());
+//      }
+//    }
+//    return result;
+//  }
 
   public String Ros2Rag.generateAspect(String rootNodeName) {
     StringBuilder sb = new StringBuilder();
     rootNode = getProgram().resolveTypeDecl(rootNodeName);
-    generateMqttAspect(sb);
-    generateGrammarExtension(sb);
-    return sb.toString();
-  }
-
-  public void Ros2Rag.generateMqttAspect(StringBuilder sb) {
-    String rootNodeName = rootNode.getName();
     com.github.mustachejava.MustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
-    com.github.mustachejava.Mustache m = mf.compile("mqtt.mustache");
+    com.github.mustachejava.Mustache m = mf.compile("ros2rag.mustache");
     m.execute(new java.io.PrintWriter(new org.jastadd.ros2rag.compiler.AppendableWriter(sb)), this);
+//    generateMqttAspect(sb);
+//    generateGrammarExtension(sb);
+    return sb.toString();
   }
-
-  public void Ros2Rag.generateGrammarExtension(StringBuilder sb) {
-    sb.append("aspect ROS2RAG {\n");
-
-    for (UpdateDefinition def : getUpdateDefinitionList()) {
-      def.generateAspect(sb);
-    }
-    for (MappingDefinition def : allMappingDefinitions()) {
-      def.generateAspect(sb);
-    }
-    for (DependencyDefinition def : getDependencyDefinitionList()) {
-      def.generateAspect(sb);
-    }
-    for (TokenComponent token : getProgram().allTokenComponents()) {
-      token.generateAspect(sb);
-    }
-
-    sb.append("}\n");
-  }
-
-  abstract void UpdateDefinition.generateAspect(StringBuilder sb);
-
-  String TokenUpdateDefinition.generateMappingApplication(StringBuilder sb, int indent,
-      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 = effectiveMappings().get(effectiveMappings().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 : effectiveMappings()) {
-      String resultVariableName = resultVariablePrefix + 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()) {
-      MappingDefinition lastMapping = effectiveMappings().get(effectiveMappings().size() - 1);
-      sb.append(ind(indent)).append("if (");
-      if (lastMapping.getToType().isArray()) {
-        sb.append("java.util.Arrays.equals(").append(preemptiveExpectedValue())
-          .append(", ").append(inputVariableName).append(")");
-      } else {
-        sb.append(preemptiveExpectedValue());
-        if (getToken().isPrimitiveType() && lastMapping.getToType().isPrimitiveType()) {
-          sb.append(" == ").append(inputVariableName);
-        } else if (lastMapping.isDefaultMappingDefinition()) {
-          sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
-            .append(inputVariableName).append(")");
-        } else {
-          sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
-            .append(inputVariableName).append(")").append(" : ")
-            .append(inputVariableName).append(" == null");
-        }
-      }
-      sb.append(") { ").append(preemptiveReturnStatement()).append(" }\n");
-    }
-    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;";
-
-  @Override
-  void ReadFromMqttDefinition.generateAspect(StringBuilder sb) {
-    sb.append(ind(1)).append("public void ").append(getToken().containingTypeDecl().getName()).append(".")
-      .append(connectMethod()).append("(String topic) {\n");
-    sb.append(ind(2)).append(mqttUpdaterAttribute()).append("().newConnection(topic, message -> {\n");
-    String lastResult = generateMappingApplication(sb, 3, "message");
-    if (loggingEnabledForReads) {
-      sb.append(ind(3)).append("System.out.println(\"[Read] \" + topic + \" -> ")
-        .append(getToken().getName()).append(" = \" + ").append(lastResult)
-        .append(");\n");
-    }
-    sb.append(ind(3)).append("set").append(getToken().getName()).append("(").append(lastResult).append(");\n");
-    sb.append(ind(2)).append("});\n");
-    sb.append(ind(1)).append("}\n\n");
-  }
-
-  @Override
-  void WriteToMqttDefinition.generateAspect(StringBuilder sb) {
-    String parentTypeName = getToken().containingTypeDecl().getName();
-    // fields
-    sb.append(ind(1)).append("private String ").append(parentTypeName).append(".")
-      .append(writeTopic()).append(" = null;\n");
-    sb.append(ind(1)).append("private byte[] ").append(parentTypeName).append(".")
-      .append(lastValue()).append(" = null;\n");
-
-    // connect method
-    sb.append(ind(1)).append("public void ").append(parentTypeName).append(".")
-      .append(connectMethod()).append("(String topic, boolean writeCurrentValue) {\n");
-    sb.append(ind(2)).append(writeTopic()).append(" = topic;\n");
-    sb.append(ind(2)).append(updateMethod()).append("();\n");
-    sb.append(ind(2)).append("if (writeCurrentValue) {\n");
-    sb.append(ind(3)).append(writeMethod()).append("();\n");
-    sb.append(ind(2)).append("}\n");
-    sb.append(ind(1)).append("}\n\n");
-
-    // update method
-    sb.append(ind(1)).append("protected boolean ").append(parentTypeName).append(".")
-      .append(updateMethod()).append("() {\n");
-    sb.append(ind(2)).append(tokenResetMethod()).append("();\n");
-    String lastResult = generateMappingApplication(sb, 2, "get" + getToken().getName() + "()");
-    sb.append(ind(2)).append(lastValue()).append(" = ").append(lastResult).append(";\n");
-    sb.append(ind(2)).append("return true;\n");
-    sb.append(ind(1)).append("}\n\n");
-
-    // write method
-    sb.append(ind(1)).append("protected void ").append(parentTypeName).append(".")
-      .append(writeMethod()).append("() {\n");
-    if (loggingEnabledForWrites) {
-      sb.append(ind(2)).append("System.out.println(\"[Write] ").append(getToken().getName())
-        .append(" = \" + ")
-        .append("get").append(getToken().getName()).append("() + \" -> \" + ")
-        .append(writeTopic()).append(");\n");
-    }
-    // _mqttUpdater().publish(${writeTopic()}, ${lastValue()});
-    sb.append(ind(2)).append(mqttUpdaterAttribute()).append("().publish(")
-      .append(writeTopic()).append(", ").append(lastValue()).append(");\n");
-    sb.append(ind(1)).append("}\n\n");
-  }
-
-  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(") throws Exception {\n");
-    for (String line : getContent().split("\n")) {
-      if (!line.trim().isEmpty()) {
-        sb.append(ind(2)).append(line).append("\n");
-      }
-    }
-    sb.append(ind(1)).append("}\n\n");
-  }
-
-  void DependencyDefinition.generateAspect(StringBuilder sb) {
-    String targetParentTypeName = getTarget().containingTypeDecl().getName();
-    String sourceParentTypeName = getSource().containingTypeDecl().getName();
-
-    // dependency method
-    sb.append(ind(1)).append("public void ").append(targetParentTypeName).append(".")
-      .append(dependencyMethod()).append("(").append(sourceParentTypeName).append(" source) {\n");
-    sb.append(ind(2)).append("add").append(internalRelationPrefix()).append("Source(source);\n");
-    sb.append(ind(1)).append("}\n\n");
-  }
-
-  void TokenComponent.generateAspect(StringBuilder sb) {
-    if (getDependencySourceDefinitionList().isEmpty()) { return; }
-
-    String parentTypeName = containingTypeDecl().getName();
-    // virtual setter
-    sb.append(ind(1)).append("public ").append(parentTypeName).append(" ")
-      .append(parentTypeName).append(".set").append(getName()).append("(")
-      .append(getJavaTypeUse().prettyPrint()).append(" value) {\n");
-    sb.append(ind(2)).append("set").append(internalName()).append("(value);\n");
-
-    for (DependencyDefinition dependencyDefinition : getDependencySourceDefinitionList()) {
-      String targetParentTypeName = dependencyDefinition.getTarget().containingTypeDecl().getName();
-      sb.append(ind(2)).append("for (").append(targetParentTypeName).append(" target : get")
-        .append(dependencyDefinition.internalRelationPrefix()).append("TargetList()) {\n");
-      sb.append(ind(3)).append("if (target.")
-        .append(dependencyDefinition.targetUpdateDefinition().updateMethod())
-        .append("()) {\n");
-      sb.append(ind(4)).append("target.")
-        .append(dependencyDefinition.targetUpdateDefinition().writeMethod())
-        .append("();\n");
-      sb.append(ind(3)).append("}\n");
-      sb.append(ind(2)).append("}\n");
-    }
-    sb.append(ind(2)).append("return this;\n");
-    sb.append(ind(1)).append("}\n\n");
-
-    // virtual getter
-    sb.append(ind(1)).append("public ").append(getJavaTypeUse().prettyPrint())
-      .append(" ").append(parentTypeName).append(".get").append(getName()).append("() {\n");
-    sb.append(ind(2)).append("return get").append(internalName()).append("();\n");
-    sb.append(ind(1)).append("}\n\n");
-  }
+//
+//  public void Ros2Rag.generateMqttAspect(StringBuilder sb) {
+//    String rootNodeName = rootNode.getName();
+//    com.github.mustachejava.MustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
+//    com.github.mustachejava.Mustache m = mf.compile("mqtt.mustache");
+//    m.execute(new java.io.PrintWriter(new org.jastadd.ros2rag.compiler.AppendableWriter(sb)), this);
+//  }
+//
+//  public void Ros2Rag.generateGrammarExtension(StringBuilder sb) {
+//    sb.append("aspect ROS2RAG {\n");
+//
+//    for (UpdateDefinition def : getUpdateDefinitionList()) {
+//      def.generateAspect(sb);
+//    }
+//    for (MappingDefinition def : allMappingDefinitions()) {
+//      def.generateAspect(sb);
+//    }
+//    for (DependencyDefinition def : getDependencyDefinitionList()) {
+//      def.generateAspect(sb);
+//    }
+//    for (TokenComponent token : getProgram().allTokenComponents()) {
+//      token.generateAspect(sb);
+//    }
+//
+//    sb.append("}\n");
+//  }
+//
+//  abstract void UpdateDefinition.generateAspect(StringBuilder sb);
+//
+//  String TokenUpdateDefinition.generateMappingApplication(StringBuilder sb, int indent,
+//      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 = effectiveMappings().get(effectiveMappings().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 : effectiveMappings()) {
+//      String resultVariableName = resultVariablePrefix + 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()) {
+//      MappingDefinition lastMapping = effectiveMappings().get(effectiveMappings().size() - 1);
+//      sb.append(ind(indent)).append("if (");
+//      if (lastMapping.getToType().isArray()) {
+//        sb.append("java.util.Arrays.equals(").append(preemptiveExpectedValue())
+//          .append(", ").append(inputVariableName).append(")");
+//      } else {
+//        sb.append(preemptiveExpectedValue());
+//        if (getToken().isPrimitiveType() && lastMapping.getToType().isPrimitiveType()) {
+//          sb.append(" == ").append(inputVariableName);
+//        } else if (lastMapping.isDefaultMappingDefinition()) {
+//          sb.append(" != null && ").append(preemptiveExpectedValue()).append(".equals(")
+//            .append(inputVariableName).append(")");
+//        } else {
+//          sb.append(" != null ? ").append(preemptiveExpectedValue()).append(".equals(")
+//            .append(inputVariableName).append(")").append(" : ")
+//            .append(inputVariableName).append(" == null");
+//        }
+//      }
+//      sb.append(") { ").append(preemptiveReturnStatement()).append(" }\n");
+//    }
+//    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;";
+//
+//  @Override
+//  void ReadFromMqttDefinition.generateAspect(StringBuilder sb) {
+//    sb.append(ind(1)).append("public void ").append(getToken().containingTypeDecl().getName()).append(".")
+//      .append(connectMethod()).append("(String topic) {\n");
+//    sb.append(ind(2)).append(mqttUpdaterAttribute()).append("().newConnection(topic, message -> {\n");
+//    String lastResult = generateMappingApplication(sb, 3, "message");
+//    if (loggingEnabledForReads) {
+//      sb.append(ind(3)).append("System.out.println(\"[Read] \" + topic + \" -> ")
+//        .append(getToken().getName()).append(" = \" + ").append(lastResult)
+//        .append(");\n");
+//    }
+//    sb.append(ind(3)).append("set").append(getToken().getName()).append("(").append(lastResult).append(");\n");
+//    sb.append(ind(2)).append("});\n");
+//    sb.append(ind(1)).append("}\n\n");
+//  }
+//
+//  @Override
+//  void WriteToMqttDefinition.generateAspect(StringBuilder sb) {
+//    String parentTypeName = getToken().containingTypeDecl().getName();
+//    // fields
+//    sb.append(ind(1)).append("private String ").append(parentTypeName).append(".")
+//      .append(writeTopic()).append(" = null;\n");
+//    sb.append(ind(1)).append("private byte[] ").append(parentTypeName).append(".")
+//      .append(lastValue()).append(" = null;\n");
+//
+//    // connect method
+//    sb.append(ind(1)).append("public void ").append(parentTypeName).append(".")
+//      .append(connectMethod()).append("(String topic, boolean writeCurrentValue) {\n");
+//    sb.append(ind(2)).append(writeTopic()).append(" = topic;\n");
+//    sb.append(ind(2)).append(updateMethod()).append("();\n");
+//    sb.append(ind(2)).append("if (writeCurrentValue) {\n");
+//    sb.append(ind(3)).append(writeMethod()).append("();\n");
+//    sb.append(ind(2)).append("}\n");
+//    sb.append(ind(1)).append("}\n\n");
+//
+//    // update method
+//    sb.append(ind(1)).append("protected boolean ").append(parentTypeName).append(".")
+//      .append(updateMethod()).append("() {\n");
+//    sb.append(ind(2)).append(tokenResetMethod()).append("();\n");
+//    String lastResult = generateMappingApplication(sb, 2, "get" + getToken().getName() + "()");
+//    sb.append(ind(2)).append(lastValue()).append(" = ").append(lastResult).append(";\n");
+//    sb.append(ind(2)).append("return true;\n");
+//    sb.append(ind(1)).append("}\n\n");
+//
+//    // write method
+//    sb.append(ind(1)).append("protected void ").append(parentTypeName).append(".")
+//      .append(writeMethod()).append("() {\n");
+//    if (loggingEnabledForWrites) {
+//      sb.append(ind(2)).append("System.out.println(\"[Write] ").append(getToken().getName())
+//        .append(" = \" + ")
+//        .append("get").append(getToken().getName()).append("() + \" -> \" + ")
+//        .append(writeTopic()).append(");\n");
+//    }
+//    // _mqttUpdater().publish(${writeTopic()}, ${lastValue()});
+//    sb.append(ind(2)).append(mqttUpdaterAttribute()).append("().publish(")
+//      .append(writeTopic()).append(", ").append(lastValue()).append(");\n");
+//    sb.append(ind(1)).append("}\n\n");
+//  }
+//
+//  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(") throws Exception {\n");
+//    for (String line : getContent().split("\n")) {
+//      if (!line.trim().isEmpty()) {
+//        sb.append(ind(2)).append(line).append("\n");
+//      }
+//    }
+//    sb.append(ind(1)).append("}\n\n");
+//  }
+//
+//  void DependencyDefinition.generateAspect(StringBuilder sb) {
+//    String targetParentTypeName = getTarget().containingTypeDecl().getName();
+//    String sourceParentTypeName = getSource().containingTypeDecl().getName();
+//
+//    // dependency method
+//    sb.append(ind(1)).append("public void ").append(targetParentTypeName).append(".")
+//      .append(dependencyMethod()).append("(").append(sourceParentTypeName).append(" source) {\n");
+//    sb.append(ind(2)).append("add").append(internalRelationPrefix()).append("Source(source);\n");
+//    sb.append(ind(1)).append("}\n\n");
+//  }
+//
+//  void TokenComponent.generateAspect(StringBuilder sb) {
+//    if (getDependencySourceDefinitionList().isEmpty()) { return; }
+//
+//    String parentTypeName = containingTypeDecl().getName();
+//    // virtual setter
+//    sb.append(ind(1)).append("public ").append(parentTypeName).append(" ")
+//      .append(parentTypeName).append(".set").append(getName()).append("(")
+//      .append(getJavaTypeUse().prettyPrint()).append(" value) {\n");
+//    sb.append(ind(2)).append("set").append(internalName()).append("(value);\n");
+//
+//    for (DependencyDefinition dependencyDefinition : getDependencySourceDefinitionList()) {
+//      String targetParentTypeName = dependencyDefinition.getTarget().containingTypeDecl().getName();
+//      sb.append(ind(2)).append("for (").append(targetParentTypeName).append(" target : get")
+//        .append(dependencyDefinition.internalRelationPrefix()).append("TargetList()) {\n");
+//      sb.append(ind(3)).append("if (target.")
+//        .append(dependencyDefinition.targetUpdateDefinition().updateMethod())
+//        .append("()) {\n");
+//      sb.append(ind(4)).append("target.")
+//        .append(dependencyDefinition.targetUpdateDefinition().writeMethod())
+//        .append("();\n");
+//      sb.append(ind(3)).append("}\n");
+//      sb.append(ind(2)).append("}\n");
+//    }
+//    sb.append(ind(2)).append("return this;\n");
+//    sb.append(ind(1)).append("}\n\n");
+//
+//    // virtual getter
+//    sb.append(ind(1)).append("public ").append(getJavaTypeUse().prettyPrint())
+//      .append(" ").append(parentTypeName).append(".get").append(getName()).append("() {\n");
+//    sb.append(ind(2)).append("return get").append(internalName()).append("();\n");
+//    sb.append(ind(1)).append("}\n\n");
+//  }
 }
 
 aspect RelationGeneration {
diff --git a/src/main/resources/mqtt.mustache b/src/main/resources/mqtt.mustache
index 33e3f4ee001d889575c264f617f37d04dc574a97..3386b2ee72e5648ad8c1e4a1cadb524eca38f97d 100644
--- a/src/main/resources/mqtt.mustache
+++ b/src/main/resources/mqtt.mustache
@@ -16,7 +16,7 @@ aspect MQTT {
   }
 
   inh MqttUpdater ASTNode.{{mqttUpdaterAttribute}}();
-  {{#rootTypeChildren}}
+  {{#RootTypeChildren}}
   eq {{rootNodeName}}.get{{name}}().{{mqttUpdaterAttribute}}() = {{mqttUpdaterField}};
-  {{/rootTypeChildren}}
+  {{/RootTypeChildren}}
 }
diff --git a/src/main/resources/readDefinition.mustache b/src/main/resources/readDefinition.mustache
index 4d07c8fa2d1464ad774badfa02d9b5e1ac774e7e..f908ef166db8eb781d7b7d46e7bae1719ea5fb1d 100644
--- a/src/main/resources/readDefinition.mustache
+++ b/src/main/resources/readDefinition.mustache
@@ -2,8 +2,8 @@
     {{mqttUpdaterAttribute}}().newConnection(topic, message -> {
       {{> mappingApplication}}
       {{#loggingEnabledForReads}}
-      System.out.println("[Read] " + topic + " -> {{TokenName}} = " + {{lastResult}});{{!lastResult has to be a new attribute}}
+      System.out.println("[Read] " + topic + " -> {{tokenName}} = " + {{lastResult}});{{!lastResult has to be a new attribute}}
       {{/loggingEnabledForReads}}
-      set{{TokenName}}({{lastResult}});
+      set{{tokenName}}({{lastResult}});
     });
   }
diff --git a/src/main/resources/ros2rag.mustache b/src/main/resources/ros2rag.mustache
index b224c6c1018fd405ca2a5802e544295e3a5a7cfa..dd5e73cf554e35cc20da014b2d83f0db1b88521b 100644
--- a/src/main/resources/ros2rag.mustache
+++ b/src/main/resources/ros2rag.mustache
@@ -1,3 +1,4 @@
+{{> mqtt}}
 aspect ROS2RAG {
   {{#ReadDefinitions}}
     {{> readDefinition}}
diff --git a/src/main/resources/writeDefinition.mustache b/src/main/resources/writeDefinition.mustache
index d94f85d51d679cd4571979664cdcfc53fc28cc1a..81ed5f55403e2340a97b79c451fa1f841c85b1f7 100644
--- a/src/main/resources/writeDefinition.mustache
+++ b/src/main/resources/writeDefinition.mustache
@@ -18,7 +18,7 @@
 
   protected void {{parentTypeName}}.{{writeMethod}}() {
     {{#loggingEnabledForWrites}}
-    System.out.println("[Write] {{TokenName}} = " + get{{TokenName}}() + " -> {{writeTopic}});
+    System.out.println("[Write] {{tokenName}} = " + get{{tokenName}}() + " -> {{writeTopic}});
     {{/loggingEnabledForWrites}}
     {{mqttUpdateAttribute}}().publish({{writeTopic}}, {{lastValue}});
   }