diff --git a/build.gradle b/build.gradle
index a6a7882eeee6db3cc34887d5b8cce3fe267905d5..7bfebcfe84f3d6f53a6ceb997eb0108610135e31 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,7 +3,7 @@ apply plugin: 'application'
 
 sourceCompatibility = 1.8
 
-mainClassName = 'org.jastadd.ros2rag.compiler.Compiler'
+mainClassName = 'org.jastadd.ragconnect.compiler.Compiler'
 
 repositories {
     jcenter()
@@ -17,12 +17,32 @@ buildscript {
 }
 
 dependencies {
+    implementation project(':relast.preprocessor')
     implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.9.6'
     implementation group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.11.2'
     runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
     api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
 }
 
+def versionFile = 'src/main/resources/ragConnectVersion.properties'
+def oldProps = new Properties()
+
+try {
+    file(versionFile).withInputStream { stream -> oldProps.load(stream) }
+    version = oldProps['version']
+} catch (e) {
+    // this happens, if either the properties file is not present, or cannot be read from
+    throw new GradleException("File ${versionFile} not found or unreadable. Aborting.", e)
+}
+
+task newVersion() {
+    doFirst {
+        def props = new Properties()
+        props['version'] = value
+        props.store(file(versionFile).newWriter(), null)
+    }
+}
+
 sourceSets {
     main {
         java.srcDir "src/gen/java"
@@ -37,7 +57,7 @@ test {
 
 jar {
     manifest {
-        attributes "Main-Class": 'org.jastadd.ros2rag.compiler.Compiler'
+        attributes "Main-Class": 'org.jastadd.ragconnect.compiler.Compiler'
     }
 
     from {
@@ -51,47 +71,47 @@ task relast(type: JavaExec) {
 
     doFirst {
         delete "src/gen/jastadd/*.ast"
-        delete "src/gen/jastadd/Ros2Rag.jadd"
-        delete "src/gen/jastadd/Ros2RagRefResolver.jadd"
-        delete "src/gen/jastadd/Ros2RagResolverStubs.jrag"
+        delete "src/gen/jastadd/RagConnect.jadd"
+        delete "src/gen/jastadd/RagConnectRefResolver.jadd"
+        delete "src/gen/jastadd/RagConnectResolverStubs.jrag"
         mkdir  "src/gen/jastadd/"
     }
 
     args = [
             "../libs/relast.jar",
             "../relast.preprocessor/src/main/jastadd/RelAst.relast",
-            "./src/main/jastadd/Ros2Rag.relast",
+            "./src/main/jastadd/RagConnect.relast",
             "./src/main/jastadd/MustacheNodes.relast",
             "--listClass=java.util.ArrayList",
             "--jastAddList=JastAddList",
             "--useJastAddNames",
             "--file",
             "--resolverHelper",
-            "--grammarName=./src/gen/jastadd/Ros2Rag"
+            "--grammarName=./src/gen/jastadd/RagConnect"
     ]
 
     inputs.files file("../libs/relast.jar"),
             file("../relast.preprocessor/src/main/jastadd/RelAST.relast"),
-            file("./src/main/jastadd/Ros2Rag.relast")
+            file("./src/main/jastadd/RagConnect.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')
+    outputs.files file("./src/gen/jastadd/RagConnect.ast"),
+            file("./src/gen/jastadd/RagConnect.jadd"),
+            file("./src/gen/jastadd/RagConnectRefResolver.jadd"),
+            file('./src/gen/jastadd/RagConnectResolverStubs.jrag')
 }
 
 jastadd {
     configureModuleBuild()
     modules {
         //noinspection GroovyAssignabilityCheck
-        module("Ros2Rag") {
+        module("RagConnect") {
 
             java {
                 basedir ".."
                 include "relast.preprocessor/main/**/*.java"
                 include "relast.preprocessor/gen/**/*.java"
-                include "ros2rag.base/src/main/**/*.java"
-                include "ros2rag.base/src/gen/**/*.java"
+                include "ragconnect.base/src/main/**/*.java"
+                include "ragconnect.base/src/gen/**/*.java"
             }
 
             jastadd {
@@ -99,23 +119,23 @@ jastadd {
                 include "relast.preprocessor/src/main/jastadd/**/*.ast"
                 include "relast.preprocessor/src/main/jastadd/**/*.jadd"
                 include "relast.preprocessor/src/main/jastadd/**/*.jrag"
-                include "ros2rag.base/src/main/jastadd/**/*.ast"
-                include "ros2rag.base/src/main/jastadd/**/*.jadd"
-                include "ros2rag.base/src/main/jastadd/**/*.jrag"
-                include "ros2rag.base/src/gen/jastadd/**/*.ast"
-                include "ros2rag.base/src/gen/jastadd/**/*.jadd"
-                include "ros2rag.base/src/gen/jastadd/**/*.jrag"
+                include "ragconnect.base/src/main/jastadd/**/*.ast"
+                include "ragconnect.base/src/main/jastadd/**/*.jadd"
+                include "ragconnect.base/src/main/jastadd/**/*.jrag"
+                include "ragconnect.base/src/gen/jastadd/**/*.ast"
+                include "ragconnect.base/src/gen/jastadd/**/*.jadd"
+                include "ragconnect.base/src/gen/jastadd/**/*.jrag"
             }
 
             scanner {
                 basedir ".."
-                include "ros2rag.base/src/main/jastadd/scanner/Header.flex",               [-5]
+                include "ragconnect.base/src/main/jastadd/scanner/Header.flex",               [-5]
                 include "relast.preprocessor/src/main/jastadd/scanner/Preamble.flex",      [-4]
                 include "relast.preprocessor/src/main/jastadd/scanner/Macros.flex",        [-3]
-                include "ros2rag.base/src/main/jastadd/scanner/Macros.flex",               [-3]
+                include "ragconnect.base/src/main/jastadd/scanner/Macros.flex",               [-3]
                 include "relast.preprocessor/src/main/jastadd/scanner/RulesPreamble.flex", [-2]
-                include "ros2rag.base/src/main/jastadd/scanner/MappingContent.flex",       [-1]
-                include "ros2rag.base/src/main/jastadd/scanner/Keywords.flex"
+                include "ragconnect.base/src/main/jastadd/scanner/MappingContent.flex",       [-1]
+                include "ragconnect.base/src/main/jastadd/scanner/Keywords.flex"
                 include "relast.preprocessor/src/main/jastadd/scanner/Keywords.flex"
                 include "relast.preprocessor/src/main/jastadd/scanner/Symbols.flex",        [1]
                 include "relast.preprocessor/src/main/jastadd/scanner/RulesPostamble.flex", [2]
@@ -123,8 +143,8 @@ jastadd {
 
             parser {
                 basedir ".."
-                include "ros2rag.base/src/main/jastadd/parser/Preamble.parser"
-                include "ros2rag.base/src/main/jastadd/parser/Ros2Rag.parser"
+                include "ragconnect.base/src/main/jastadd/parser/Preamble.parser"
+                include "ragconnect.base/src/main/jastadd/parser/RagConnect.parser"
                 include "relast.preprocessor/src/main/jastadd/parser/RelAst.parser"
             }
         }
@@ -141,18 +161,18 @@ jastadd {
 
     }
 
-    module = "Ros2Rag"
+    module = "RagConnect"
 
-    astPackage = 'org.jastadd.ros2rag.ast'
+    astPackage = 'org.jastadd.ragconnect.ast'
 
-    parser.name = 'Ros2RagParser'
+    parser.name = 'RagConnectParser'
 
     genDir = 'src/gen/java'
 
     buildInfoDir = 'src/gen-res'
 
-    scanner.genDir = "src/gen/java/org/jastadd/ros2rag/scanner"
-    parser.genDir = "src/gen/java/org/jastadd/ros2rag/parser"
+    scanner.genDir = "src/gen/java/org/jastadd/ragconnect/scanner"
+    parser.genDir = "src/gen/java/org/jastadd/ragconnect/parser"
 
     jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
 }
diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag
index 228a3479df5be9d24998479bc3b48bd1626775aa..623a3f0ad8c0457d8d0606bf70dea0adfea89ea4 100644
--- a/src/main/jastadd/Analysis.jrag
+++ b/src/main/jastadd/Analysis.jrag
@@ -1,10 +1,10 @@
 aspect Analysis {
-  // --- lookupTokenUpdateDefinition ---
-  inh TokenUpdateDefinition TokenUpdateDefinition.lookupTokenUpdateDefinition(TokenComponent token);
-  eq Ros2Rag.getUpdateDefinition().lookupTokenUpdateDefinition(TokenComponent token) {
-    for (UpdateDefinition def : getUpdateDefinitionList()) {
-      if (def.isTokenUpdateDefinition() && def.asTokenUpdateDefinition().getToken().equals(token)) {
-        return def.asTokenUpdateDefinition();
+  // --- lookupTokenEndpointDefinition ---
+  inh TokenEndpointDefinition TokenEndpointDefinition.lookupTokenEndpointDefinition(TokenComponent token);
+  eq RagConnect.getEndpointDefinition().lookupTokenEndpointDefinition(TokenComponent token) {
+    for (EndpointDefinition def : getEndpointDefinitionList()) {
+      if (def.isTokenEndpointDefinition() && def.asTokenEndpointDefinition().getToken().equals(token)) {
+        return def.asTokenEndpointDefinition();
       }
     }
     return null;
@@ -12,7 +12,7 @@ aspect Analysis {
 
   // --- lookupDependencyDefinition ---
   inh DependencyDefinition DependencyDefinition.lookupDependencyDefinition(TypeDecl source, String id);
-  eq Ros2Rag.getDependencyDefinition().lookupDependencyDefinition(TypeDecl source, String id) {
+  eq RagConnect.getDependencyDefinition().lookupDependencyDefinition(TypeDecl source, String id) {
     for (DependencyDefinition def : getDependencyDefinitionList()) {
       if (def.getID().equals(id) && def.getSource().containingTypeDecl().equals(source)) {
         return def;
@@ -22,6 +22,6 @@ aspect Analysis {
   }
 
   // --- isAlreadyDefined ---
-  syn boolean TokenUpdateDefinition.isAlreadyDefined() = lookupTokenUpdateDefinition(getToken()) != this;
+  syn boolean TokenEndpointDefinition.isAlreadyDefined() = lookupTokenEndpointDefinition(getToken()) != this;
   syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this;
 }
diff --git a/src/main/jastadd/Errors.jrag b/src/main/jastadd/Errors.jrag
index ef223a4081e169273555140a35a9f8b47876109d..bfee2545d4bee28223b04ce931ccd6a6429cf13f 100644
--- a/src/main/jastadd/Errors.jrag
+++ b/src/main/jastadd/Errors.jrag
@@ -3,50 +3,50 @@ import java.util.TreeSet;
 import java.util.LinkedList;
 
 aspect Errors {
-  coll Set<ErrorMessage> Ros2Rag.errors()
+  coll Set<ErrorMessage> RagConnect.errors()
     [new TreeSet<ErrorMessage>()]
-    root Ros2Rag;
+    root RagConnect;
 
-    ReadFromMqttDefinition contributes error("Read definition already defined for " + getToken().getName())
+    ReceiveFromMqttDefinition contributes error("Receive definition already defined for " + getToken().getName())
       when isAlreadyDefined()
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
-    ReadFromMqttDefinition contributes error("Reading target token must not be an NTA token!")
+    ReceiveFromMqttDefinition contributes error("Receiving target token must not be an NTA token!")
       when getToken().getNTA()
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
     // if first mapping is null, then suitableDefaultMapping() == null
-    ReadFromMqttDefinition contributes error("No suitable default mapping found for type " +
+    ReceiveFromMqttDefinition contributes error("No suitable default mapping found for type " +
       ((getMappingList().isEmpty())
         ? getToken().getJavaTypeUse().prettyPrint()
         : getMappingList().get(0).getFromType().prettyPrint()))
       when effectiveMappings().get(0) == null
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
-    ReadFromMqttDefinition contributes error("to-type of last mapping must be type of the Token!")
+    ReceiveFromMqttDefinition contributes error("to-type of last mapping must be type of the Token!")
       when getToken().getJavaTypeUse().prettyPrint().equals(
           effectiveMappings().get(effectiveMappings().size() - 1))
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
-    WriteToMqttDefinition contributes error("Writing target token must be an NTA token!")
+    SendToMqttDefinition contributes error("Sending target token must be an NTA token!")
       when !getToken().getNTA()
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
-    WriteToMqttDefinition contributes error("Write definition already defined for " + getToken().getName())
+    SendToMqttDefinition contributes error("Send definition already defined for " + getToken().getName())
       when isAlreadyDefined()
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
     DependencyDefinition contributes error("Dependency definition already defined for " + getSource().containingTypeDecl().getName() + " with name " + getID())
       when isAlreadyDefined()
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
     DependencyDefinition contributes error("The name of a dependency definition must not be equal to a list-node on the source")
       when isAlreadyDefinedAsList()
-      to Ros2Rag.errors();
+      to RagConnect.errors();
 
-    DependencyDefinition contributes error("There must be a write update definition targeting " + getSource().parentTypeypeAndName() + " for dependency definition " + getID())
-      when targetUpdateDefinition() == null
-      to Ros2Rag.errors();
+    DependencyDefinition contributes error("There must be a send update definition targeting " + getSource().parentTypeypeAndName() + " for dependency definition " + getID())
+      when targetEndpointDefinition() == null
+      to RagConnect.errors();
 }
 
 aspect ErrorHelpers {
diff --git a/src/main/jastadd/MustacheNodes.relast b/src/main/jastadd/MustacheNodes.relast
index 69d4280f9d9038c838e83767c6e72be9a8d6d5d8..ce85caba554d1f582079b299f457d7675ab12dfa 100644
--- a/src/main/jastadd/MustacheNodes.relast
+++ b/src/main/jastadd/MustacheNodes.relast
@@ -1,20 +1,20 @@
 //TypeComponentMustache ;
 //rel TypeComponentMustache.TypeComponent -> TypeComponent ;
 
-MRos2Rag ::= ReadDefinition:MReadDefinition* WriteDefinition:MWriteDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
-abstract MUpdateDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
-MReadDefinition : MUpdateDefinition;
-MWriteDefinition : MUpdateDefinition;
+MRagConnect ::= ReceiveDefinition:MReceiveDefinition* SendDefinition:MSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent*;
+abstract MEndpointDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
+MReceiveDefinition : MEndpointDefinition;
+MSendDefinition : MEndpointDefinition;
 MMappingDefinition;
 MInnerMappingDefinition;
 MDependencyDefinition;
 MTypeComponent;
 MTokenComponent;
 
-rel MRos2Rag.Ros2Rag -> Ros2Rag;
+rel MRagConnect.RagConnect -> RagConnect;
 rel MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
-rel MReadDefinition.ReadFromMqttDefinition -> ReadFromMqttDefinition;
-rel MWriteDefinition.WriteToMqttDefinition -> WriteToMqttDefinition;
+rel MReceiveDefinition.ReceiveFromMqttDefinition -> ReceiveFromMqttDefinition;
+rel MSendDefinition.SendToMqttDefinition -> SendToMqttDefinition;
 rel MMappingDefinition.MappingDefinition -> MappingDefinition;
 rel MDependencyDefinition.DependencyDefinition -> DependencyDefinition;
 rel MTypeComponent.TypeComponent -> TypeComponent;
diff --git a/src/main/jastadd/NameResolution.jrag b/src/main/jastadd/NameResolution.jrag
index fc4485858d199f352c18fcd188914020666ef619..f282ba55983feeae814e12823ff31f1d6480b6a8 100644
--- a/src/main/jastadd/NameResolution.jrag
+++ b/src/main/jastadd/NameResolution.jrag
@@ -1,8 +1,8 @@
 aspect NameResolution {
 
-  refine RefResolverStubs eq UpdateDefinition.resolveMappingByToken(String id, int position) {
+  refine RefResolverStubs eq EndpointDefinition.resolveMappingByToken(String id, int position) {
     // return a MappingDefinition
-    for (MappingDefinition mappingDefinition : ros2rag().getMappingDefinitionList()) {
+    for (MappingDefinition mappingDefinition : ragconnect().getMappingDefinitionList()) {
       if (mappingDefinition.getID().equals(id)) {
         return mappingDefinition;
       }
diff --git a/src/main/jastadd/Navigation.jrag b/src/main/jastadd/Navigation.jrag
index a4f21e6e8d79c549a63d54474792382457bf74fd..2314386eb9f74ecb5699d6fba91956e80f75fa63 100644
--- a/src/main/jastadd/Navigation.jrag
+++ b/src/main/jastadd/Navigation.jrag
@@ -1,68 +1,48 @@
 aspect Navigation {
 
   // --- program ---
-  eq Ros2Rag.getChild().program() = getProgram();
-  eq MRos2Rag.getChild().program() = getRos2Rag().program();
+  eq RagConnect.getChild().program() = getProgram();
+  eq MRagConnect.getChild().program() = getRagConnect().program();
 
-  // --- ros2rag ---
-  inh Ros2Rag ASTNode.ros2rag();
-  eq Ros2Rag.getChild().ros2rag() = this;
-  eq MRos2Rag.getChild().ros2rag() = getRos2Rag();
+  // --- ragconnect ---
+  inh RagConnect ASTNode.ragconnect();
+  eq RagConnect.getChild().ragconnect() = this;
+  eq MRagConnect.getChild().ragconnect() = getRagConnect();
 
-  // --- containedFile (first equation should be in preprocessor) ---
-  eq Program.getChild().containedFile() = null;
-  eq Ros2Rag.getChild().containedFile() = null;
+  // --- containedFile
+  eq RagConnect.getChild().containedFile() = null;
 
-  // --- isTypeComponent (should be in preprocessor) ---
-  syn boolean Component.isTypeComponent() = false;
-  eq TypeComponent.isTypeComponent() = true;
+  // --- containedFileName ---
+  eq RagConnect.getChild().containedFileName() = getFileName();
+  eq MRagConnect.getChild().containedFileName() = null;
 
-  // --- asTypeComponent (should be in preprocessor) ---
-  syn TypeComponent Component.asTypeComponent() = null;
-  eq TypeComponent.asTypeComponent() = this;
+  // --- isTokenEndpointDefinition ---
+  syn boolean EndpointDefinition.isTokenEndpointDefinition() = false;
+  eq TokenEndpointDefinition.isTokenEndpointDefinition() = true;
 
-  // --- isListComponent (should be in preprocessor) ---
-  syn boolean Component.isListComponent() = false;
-  eq ListComponent.isListComponent() = true;
+  // --- asTokenEndpointDefinition ---
+  syn TokenEndpointDefinition EndpointDefinition.asTokenEndpointDefinition() = null;
+  eq TokenEndpointDefinition.asTokenEndpointDefinition() = this;
 
-  // --- asListComponent (should be in preprocessor) ---
-  syn ListComponent Component.asListComponent() = null;
-  eq ListComponent.asListComponent() = this;
+  // --- isSendToMqttDefinition ---
+  syn boolean EndpointDefinition.isSendToMqttDefinition() = false;
+  eq SendToMqttDefinition.isSendToMqttDefinition() = true;
 
-  // --- containedFileName (should replace containedFile in preprocessor) ---
-  inh String ASTNode.containedFileName();
-  eq GrammarFile.getChild().containedFileName() = getFileName();
-  eq Ros2Rag.getChild().containedFileName() = getFileName();
-  eq Program.getChild().containedFileName() = null;
-  eq MRos2Rag.getChild().containedFileName() = null;
+  // --- asSendToMqttDefinition ---
+  syn SendToMqttDefinition EndpointDefinition.asSendToMqttDefinition() = null;
+  eq SendToMqttDefinition.asSendToMqttDefinition() = this;
 
-  // --- isTokenUpdateDefinition ---
-  syn boolean UpdateDefinition.isTokenUpdateDefinition() = false;
-  eq TokenUpdateDefinition.isTokenUpdateDefinition() = true;
+  // --- asReceiveFromMqttDefinition ---
+  syn ReceiveFromMqttDefinition EndpointDefinition.asReceiveFromMqttDefinition() = null;
+  eq ReceiveFromMqttDefinition.asReceiveFromMqttDefinition() = this;
 
-  // --- asTokenUpdateDefinition ---
-  syn TokenUpdateDefinition UpdateDefinition.asTokenUpdateDefinition() = null;
-  eq TokenUpdateDefinition.asTokenUpdateDefinition() = this;
-
-  // --- isWriteToMqttDefinition ---
-  syn boolean UpdateDefinition.isWriteToMqttDefinition() = false;
-  eq WriteToMqttDefinition.isWriteToMqttDefinition() = true;
-
-  // --- asWriteToMqttDefinition ---
-  syn WriteToMqttDefinition UpdateDefinition.asWriteToMqttDefinition() = null;
-  eq WriteToMqttDefinition.asWriteToMqttDefinition() = this;
-
-  // --- asReadFromMqttDefinition ---
-  syn ReadFromMqttDefinition UpdateDefinition.asReadFromMqttDefinition() = null;
-  eq ReadFromMqttDefinition.asReadFromMqttDefinition() = this;
-
-  // --- targetUpdateDefinition ---
-  syn WriteToMqttDefinition DependencyDefinition.targetUpdateDefinition() {
+  // --- targetEndpointDefinition ---
+  syn SendToMqttDefinition DependencyDefinition.targetEndpointDefinition() {
     // resolve definition in here, as we do not need resolveMethod in any other place (yet)
-    for (UpdateDefinition updateDefinition : ros2rag().getUpdateDefinitionList()) {
-      if (updateDefinition.isWriteToMqttDefinition() &&
-          updateDefinition.asWriteToMqttDefinition().getToken().equals(this.getTarget())) {
-        return updateDefinition.asWriteToMqttDefinition();
+    for (EndpointDefinition endpointDefinition : ragconnect().getEndpointDefinitionList()) {
+      if (endpointDefinition.isSendToMqttDefinition() &&
+          endpointDefinition.asSendToMqttDefinition().getToken().equals(this.getTarget())) {
+        return endpointDefinition.asSendToMqttDefinition();
       }
     }
     return null;
@@ -71,10 +51,4 @@ aspect Navigation {
   // --- isDefaultMappingDefinition ---
   syn boolean MappingDefinition.isDefaultMappingDefinition() = false;
   eq DefaultMappingDefinition.isDefaultMappingDefinition() = true;
-
-  // --- allTokenComponents ---
-  coll java.util.Set<TokenComponent> Program.allTokenComponents() [new java.util.HashSet<>()] root Program;
-  TokenComponent contributes this
-    to Program.allTokenComponents()
-    for program();
 }
diff --git a/src/main/jastadd/Ros2Rag.relast b/src/main/jastadd/RagConnect.relast
similarity index 55%
rename from src/main/jastadd/Ros2Rag.relast
rename to src/main/jastadd/RagConnect.relast
index e1a84e8beac44fcbc23d09fc56ed536586bde4e8..d30116efae1a6735e88922e31f42f99911c6532a 100644
--- a/src/main/jastadd/Ros2Rag.relast
+++ b/src/main/jastadd/RagConnect.relast
@@ -1,14 +1,14 @@
-Ros2Rag ::= UpdateDefinition* DependencyDefinition* MappingDefinition* Program <FileName> ;
+RagConnect ::= EndpointDefinition* DependencyDefinition* MappingDefinition* Program <FileName> ;
 
-abstract UpdateDefinition ::= <AlwaysApply:boolean> ;
+abstract EndpointDefinition ::= <AlwaysApply:boolean> ;
 
-rel UpdateDefinition.Mapping* -> MappingDefinition;
+rel EndpointDefinition.Mapping* -> MappingDefinition;
 
-abstract TokenUpdateDefinition : UpdateDefinition;
-rel TokenUpdateDefinition.Token -> TokenComponent;
+abstract TokenEndpointDefinition : EndpointDefinition;
+rel TokenEndpointDefinition.Token -> TokenComponent;
 
-ReadFromMqttDefinition : TokenUpdateDefinition;
-WriteToMqttDefinition  : TokenUpdateDefinition;
+ReceiveFromMqttDefinition : TokenEndpointDefinition;
+SendToMqttDefinition  : TokenEndpointDefinition;
 
 DependencyDefinition ::= <ID>;
 rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
diff --git a/src/main/jastadd/backend/Generation.jadd b/src/main/jastadd/backend/Generation.jadd
index 9179b3d5ad520e4a3255a5b26c7ea86deaeef50b..067626ed42f12add896ca4eea7c65917309c0e2e 100644
--- a/src/main/jastadd/backend/Generation.jadd
+++ b/src/main/jastadd/backend/Generation.jadd
@@ -26,39 +26,40 @@ aspect GenerationUtils {
 */
 
 aspect AttributesForMustache {
-  // --- MRos2Rag ---
-  eq MRos2Rag.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
-  eq MRos2Rag.getChild().mqttHandlerField() = mqttHandlerField();
+  // --- MRagConnect ---
+  eq MRagConnect.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
+  eq MRagConnect.getChild().mqttHandlerField() = mqttHandlerField();
+  eq MRagConnect.getRootTypeComponent(int i).isFirst() = i == 0;
 
-  syn String MRos2Rag.mqttHandlerAttribute() = getRos2Rag().mqttHandlerAttribute();
-  syn String MRos2Rag.mqttHandlerField() = getRos2Rag().mqttHandlerField();
-  syn String MRos2Rag.mqttSetHostMethod() = getRos2Rag().mqttSetHostMethod();
-  syn String MRos2Rag.mqttWaitUntilReadyMethod() = getRos2Rag().mqttWaitUntilReadyMethod();
-  syn String MRos2Rag.mqttCloseMethod() = getRos2Rag().mqttCloseMethod();
+  syn String MRagConnect.mqttHandlerAttribute() = getRagConnect().mqttHandlerAttribute();
+  syn String MRagConnect.mqttHandlerField() = getRagConnect().mqttHandlerField();
+  syn String MRagConnect.mqttSetHostMethod() = getRagConnect().mqttSetHostMethod();
+  syn String MRagConnect.mqttWaitUntilReadyMethod() = getRagConnect().mqttWaitUntilReadyMethod();
+  syn String MRagConnect.mqttCloseMethod() = getRagConnect().mqttCloseMethod();
 
-  // --- MUpdateDefinition ---
-  syn String MUpdateDefinition.preemptiveExpectedValue();
-  syn String MUpdateDefinition.preemptiveReturn();
-  syn TokenUpdateDefinition MUpdateDefinition.updateDef();
-  syn String MUpdateDefinition.firstInputVarName();
+  // --- MEndpointDefinition ---
+  syn String MEndpointDefinition.preemptiveExpectedValue();
+  syn String MEndpointDefinition.preemptiveReturn();
+  syn TokenEndpointDefinition MEndpointDefinition.endpointDef();
+  syn String MEndpointDefinition.firstInputVarName();
 
-  eq MUpdateDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
-  eq MUpdateDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
-  eq MUpdateDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : resultVarPrefix() + getInnerMappingDefinition(i - 1).getMappingDefinition().methodName();
+  eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
+  eq MEndpointDefinition.getInnerMappingDefinition().resultVarPrefix() = resultVarPrefix();
+  eq MEndpointDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : resultVarPrefix() + getInnerMappingDefinition(i - 1).getMappingDefinition().methodName();
 
-  inh String MUpdateDefinition.mqttHandlerAttribute();
+  inh String MEndpointDefinition.mqttHandlerAttribute();
 
-  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(getNumInnerMappingDefinition() - 1);
-  syn String MUpdateDefinition.lastDefinitionToType() = lastDefinition().ToType();
-  syn String MUpdateDefinition.lastDefinitionName() = lastDefinition().methodName();
-  syn String MUpdateDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
-  syn String MUpdateDefinition.condition() {
+  syn String MEndpointDefinition.connectMethod() = endpointDef().connectMethod();
+  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
+  syn String MEndpointDefinition.parentTypeName() = token().containingTypeDecl().getName();
+  syn String MEndpointDefinition.tokenName() = token().getName();
+  syn MInnerMappingDefinition MEndpointDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
+  syn String MEndpointDefinition.lastDefinitionToType() = lastDefinition().ToType();
+  syn String MEndpointDefinition.lastDefinitionName() = lastDefinition().methodName();
+  syn String MEndpointDefinition.lastResult() = resultVarPrefix() + lastDefinitionName();
+  syn String MEndpointDefinition.condition() {
     if (lastDefinition().getMappingDefinition().getToType().isArray()) {
       return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
     }
@@ -78,23 +79,23 @@ aspect AttributesForMustache {
   syn String MInnerMappingDefinition.methodName() = getMappingDefinition().methodName();
   inh String MInnerMappingDefinition.inputVarName();
 
-  // --- MReadDefinition ---
-  eq MReadDefinition.preemptiveExpectedValue() = "get" + tokenName() + "()";
-  eq MReadDefinition.preemptiveReturn() = "return;";
-  eq MReadDefinition.updateDef() = getReadFromMqttDefinition();
-  eq MReadDefinition.firstInputVarName() = "message";
+  // --- MReceiveDefinition ---
+  eq MReceiveDefinition.preemptiveExpectedValue() = "get" + tokenName() + "()";
+  eq MReceiveDefinition.preemptiveReturn() = "return;";
+  eq MReceiveDefinition.endpointDef() = getReceiveFromMqttDefinition();
+  eq MReceiveDefinition.firstInputVarName() = "message";
 
-  // --- MWriteDefinition ---
-  eq MWriteDefinition.preemptiveExpectedValue() = lastValue();
-  eq MWriteDefinition.preemptiveReturn() = "return false;";
-  eq MWriteDefinition.updateDef() = getWriteToMqttDefinition();
-  eq MWriteDefinition.firstInputVarName() = "get" + tokenName() + "()";
+  // --- MSendDefinition ---
+  eq MSendDefinition.preemptiveExpectedValue() = lastValue();
+  eq MSendDefinition.preemptiveReturn() = "return false;";
+  eq MSendDefinition.endpointDef() = getSendToMqttDefinition();
+  eq MSendDefinition.firstInputVarName() = "get" + tokenName() + "()";
 
-  syn String MWriteDefinition.writeTopic() = getWriteToMqttDefinition().writeTopic();
-  syn String MWriteDefinition.lastValue() = getWriteToMqttDefinition().lastValue();
-  syn String MWriteDefinition.updateMethod() = getWriteToMqttDefinition().updateMethod();
-  syn String MWriteDefinition.writeMethod() = getWriteToMqttDefinition().writeMethod();
-  syn String MWriteDefinition.tokenResetMethod() = getWriteToMqttDefinition().tokenResetMethod();
+  syn String MSendDefinition.sendTopic() = getSendToMqttDefinition().sendTopic();
+  syn String MSendDefinition.lastValue() = getSendToMqttDefinition().lastValue();
+  syn String MSendDefinition.updateMethod() = getSendToMqttDefinition().updateMethod();
+  syn String MSendDefinition.writeMethod() = getSendToMqttDefinition().writeMethod();
+  syn String MSendDefinition.tokenResetMethod() = getSendToMqttDefinition().tokenResetMethod();
 
   // --- MMappingDefinition ---
   syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
@@ -108,14 +109,15 @@ aspect AttributesForMustache {
   syn String MDependencyDefinition.dependencyMethod() = getDependencyDefinition().dependencyMethod();
   syn String MDependencyDefinition.sourceParentTypeName() = getDependencyDefinition().getSource().containingTypeDecl().getName();
   syn String MDependencyDefinition.internalRelationPrefix() = getDependencyDefinition().internalRelationPrefix();
-  syn nta MUpdateDefinition MDependencyDefinition.targetUpdateDefinition() {
-    return getDependencyDefinition().targetUpdateDefinition().toMustache();
+  syn nta MEndpointDefinition MDependencyDefinition.targetEndpointDefinition() {
+    return getDependencyDefinition().targetEndpointDefinition().toMustache();
   }
 
   // --- MTypeComponent ---
   syn String MTypeComponent.name() = getTypeComponent().getName();
   inh String MTypeComponent.mqttHandlerAttribute();
   inh String MTypeComponent.mqttHandlerField();
+  inh boolean MTypeComponent.isFirst();
 
   // --- MTokenComponent ---
   syn String MTokenComponent.parentTypeName() = getTokenComponent().containingTypeDecl().getName();
@@ -124,14 +126,14 @@ aspect AttributesForMustache {
   syn String MTokenComponent.internalName() = getTokenComponent().internalName();
 
   // --- toMustache ---
-  syn lazy MRos2Rag Ros2Rag.toMustache() {
-    MRos2Rag result = new MRos2Rag();
-    result.setRos2Rag(this);
-    for (UpdateDefinition def : getUpdateDefinitionList()) {
-      if (def.isWriteToMqttDefinition()) {
-        result.addWriteDefinition(def.asWriteToMqttDefinition().toMustache());
+  syn lazy MRagConnect RagConnect.toMustache() {
+    MRagConnect result = new MRagConnect();
+    result.setRagConnect(this);
+    for (EndpointDefinition def : getEndpointDefinitionList()) {
+      if (def.isSendToMqttDefinition()) {
+        result.addSendDefinition(def.asSendToMqttDefinition().toMustache());
       } else {
-        result.addReadDefinition(def.asReadFromMqttDefinition().toMustache());
+        result.addReceiveDefinition(def.asReceiveFromMqttDefinition().toMustache());
       }
     }
     for (MappingDefinition def : allMappingDefinitions()) {
@@ -154,22 +156,22 @@ aspect AttributesForMustache {
   }
 
 //MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
-  protected void MUpdateDefinition.addInnerMappings() {
-    for (MappingDefinition def : updateDef().effectiveMappings()) {
+  protected void MEndpointDefinition.addInnerMappings() {
+    for (MappingDefinition def : endpointDef().effectiveMappings()) {
       MInnerMappingDefinition inner = new MInnerMappingDefinition();
       inner.setMappingDefinition(def);
       addInnerMappingDefinition(inner);
     }
   }
-  syn lazy MReadDefinition ReadFromMqttDefinition.toMustache() {
-    MReadDefinition result = new MReadDefinition();
-    result.setReadFromMqttDefinition(this);
+  syn lazy MReceiveDefinition ReceiveFromMqttDefinition.toMustache() {
+    MReceiveDefinition result = new MReceiveDefinition();
+    result.setReceiveFromMqttDefinition(this);
     result.addInnerMappings();
     return result;
   }
-  syn lazy MWriteDefinition WriteToMqttDefinition.toMustache() {
-    MWriteDefinition result = new MWriteDefinition();
-    result.setWriteToMqttDefinition(this);
+  syn lazy MSendDefinition SendToMqttDefinition.toMustache() {
+    MSendDefinition result = new MSendDefinition();
+    result.setSendToMqttDefinition(this);
     result.addInnerMappings();
     return result;
   }
@@ -203,12 +205,12 @@ aspect AspectGeneration {
   syn String TokenComponent.internalName() = getDependencySourceDefinitionList().isEmpty() ? externalName() : "_internal_" + getName();
   syn String TokenComponent.externalName() = getName();
 
-  syn String TokenUpdateDefinition.connectMethod() = "connect" + getToken().getName();
-  syn String WriteToMqttDefinition.writeTopic() = "_topic_" + getToken().getName();
-  syn String WriteToMqttDefinition.lastValue() = "_lastValue" + getToken().getName();
-  syn String WriteToMqttDefinition.updateMethod() = "_update_" + getToken().getName();
-  syn String WriteToMqttDefinition.writeMethod() = "_writeLastValue_" + getToken().getName();
-  syn String WriteToMqttDefinition.tokenResetMethod() = "get" + getToken().getName() + "_reset";
+  syn String TokenEndpointDefinition.connectMethod() = "connect" + getToken().getName();
+  syn String SendToMqttDefinition.sendTopic() = "_topic_" + getToken().getName();
+  syn String SendToMqttDefinition.lastValue() = "_lastValue" + getToken().getName();
+  syn String SendToMqttDefinition.updateMethod() = "_update_" + getToken().getName();
+  syn String SendToMqttDefinition.writeMethod() = "_writeLastValue_" + getToken().getName();
+  syn String SendToMqttDefinition.tokenResetMethod() = "get" + getToken().getName() + "_reset";
   syn String MappingDefinition.methodName() = "_apply_" + getID();
   syn String DependencyDefinition.dependencyMethod() = "add" +
     Character.toUpperCase(getID().charAt(0)) +
@@ -216,29 +218,29 @@ aspect AspectGeneration {
   syn String DependencyDefinition.internalRelationPrefix() = "_internal_" + getID();
   syn String DependencyDefinition.internalTokenName() = getSource().internalName();
 
-  syn String Ros2Rag.mqttHandlerAttribute() = "_mqttHandler";
-  syn String Ros2Rag.mqttHandlerField() = "_mqttHandler";
+  syn String RagConnect.mqttHandlerAttribute() = "_mqttHandler";
+  syn String RagConnect.mqttHandlerField() = "_mqttHandler";
 
-  syn String Ros2Rag.mqttSetHostMethod() = "MqttSetHost";
-  syn String Ros2Rag.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady";
-  syn String Ros2Rag.mqttCloseMethod() = "MqttCloseConnections";
+  syn String RagConnect.mqttSetHostMethod() = "MqttSetHost";
+  syn String RagConnect.mqttWaitUntilReadyMethod() = "MqttWaitUntilReady";
+  syn String RagConnect.mqttCloseMethod() = "MqttCloseConnections";
 
   // naming copy attributes
   // --- mqttHandlerAttribute ---
-  inh String UpdateDefinition.mqttHandlerAttribute();
+  inh String EndpointDefinition.mqttHandlerAttribute();
   inh String MappingDefinition.mqttHandlerAttribute();
   inh String DependencyDefinition.mqttHandlerAttribute();
-  eq Ros2Rag.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
+  eq RagConnect.getChild().mqttHandlerAttribute() = mqttHandlerAttribute();
 
   // --- rootNodeName ---
   syn String ASTNode.rootNodeName() = rootNode.getName();
 
-  public String Ros2Rag.generateAspect(String rootNodeName) {
+  public String RagConnect.generateAspect(String rootNodeName) {
     rootNode = getProgram().resolveTypeDecl(rootNodeName);
     return toMustache().generateAspect();
   }
 
-  public String MRos2Rag.generateAspect() {
+  public String MRagConnect.generateAspect() {
     StringBuilder sb = new StringBuilder();
     com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
       @Override
@@ -257,14 +259,14 @@ aspect AspectGeneration {
     };
     com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
     mf.setObjectHandler(roh);
-    com.github.mustachejava.Mustache m = mf.compile("ros2rag.mustache");
-    m.execute(new java.io.PrintWriter(new org.jastadd.ros2rag.compiler.AppendableWriter(sb)), this);
+    com.github.mustachejava.Mustache m = mf.compile("ragconnect.mustache");
+    m.execute(new java.io.PrintWriter(new org.jastadd.ragconnect.compiler.AppendableWriter(sb)), this);
     return sb.toString();
   }
 }
 
 aspect RelationGeneration {
-  syn java.util.List<Relation> Ros2Rag.additionalRelations() {
+  syn java.util.List<Relation> RagConnect.additionalRelations() {
     java.util.List<Relation> result = new java.util.ArrayList<>();
     for (DependencyDefinition dd : getDependencyDefinitionList()) {
       result.add(dd.getRelationToCreate());
@@ -280,6 +282,7 @@ aspect RelationGeneration {
     right.setType(getSource().containingTypeDecl());
     result.setLeft(left);
     result.setRight(right);
+    result.addComment(new WhitespaceComment("\n"));
     return result;
   }
 }
diff --git a/src/main/jastadd/backend/Mappings.jrag b/src/main/jastadd/backend/Mappings.jrag
index 600ce92ee064f45fe0f41860dd3ab0bc5e334bd3..07cbf5b81a531638ac092635f915ed856a65df4c 100644
--- a/src/main/jastadd/backend/Mappings.jrag
+++ b/src/main/jastadd/backend/Mappings.jrag
@@ -1,6 +1,6 @@
 aspect DefaultMappings {
 
-  private DefaultMappingDefinition Ros2Rag.baseDefaultMappingDefinitionFromBytes(String typeName) {
+  private DefaultMappingDefinition RagConnect.baseDefaultMappingDefinitionFromBytes(String typeName) {
     DefaultMappingDefinition result = new DefaultMappingDefinition();
     result.setID("_DefaultBytesTo" + Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1) + "Mapping");
     result.setFromType(new JavaArrayMappingDefinitionType(new SimpleJavaTypeUse("byte")));
@@ -9,7 +9,7 @@ aspect DefaultMappings {
     return result;
   }
 
-  private DefaultMappingDefinition Ros2Rag.baseDefaultMappingDefinitionToBytes(String typeName) {
+  private DefaultMappingDefinition RagConnect.baseDefaultMappingDefinitionToBytes(String typeName) {
     DefaultMappingDefinition result = new DefaultMappingDefinition();
     result.setID("_Default" + Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1) + "ToBytesMapping");
     result.setFromType(new JavaMappingDefinitionType(new SimpleJavaTypeUse(typeName)));
@@ -18,85 +18,85 @@ aspect DefaultMappings {
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToIntMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToIntMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("int");
     result.setContent("return java.nio.ByteBuffer.wrap(bytes).getInt();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToShortMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToShortMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("short");
     result.setContent("return java.nio.ByteBuffer.wrap(bytes).getShort();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToLongMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToLongMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("long");
     result.setContent("return java.nio.ByteBuffer.wrap(bytes).getLong();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToFloatMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToFloatMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("float");
     result.setContent("return java.nio.ByteBuffer.wrap(bytes).getFloat();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToDoubleMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToDoubleMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("double");
     result.setContent("return java.nio.ByteBuffer.wrap(bytes).getDouble();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToCharMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToCharMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("char");
     result.setContent("return java.nio.ByteBuffer.wrap(bytes).getChar();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultBytesToStringMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultBytesToStringMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionFromBytes("String");
     result.setContent("return new String(bytes);");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultIntToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultIntToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("int");
     result.setContent("return java.nio.ByteBuffer.allocate(4).putInt(input).array();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultShortToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultShortToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("short");
     result.setContent("return java.nio.ByteBuffer.allocate(2).putShort(input).array();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultLongToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultLongToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("long");
     result.setContent("return java.nio.ByteBuffer.allocate(8).putLong(input).array();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultFloatToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultFloatToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("float");
     result.setContent("return java.nio.ByteBuffer.allocate(4).putFloat(input).array();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultDoubleToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultDoubleToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("double");
     result.setContent("return java.nio.ByteBuffer.allocate(8).putDouble(input).array();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultCharToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultCharToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("char");
     result.setContent("return java.nio.ByteBuffer.allocate(2).putChar(input).array();");
     return result;
   }
 
-  syn nta DefaultMappingDefinition Ros2Rag.defaultStringToBytesMapping() {
+  syn nta DefaultMappingDefinition RagConnect.defaultStringToBytesMapping() {
     DefaultMappingDefinition result = baseDefaultMappingDefinitionToBytes("String");
     result.setContent("return input.getBytes();");
     return result;
@@ -105,8 +105,8 @@ aspect DefaultMappings {
 
 aspect Mappings {
   // --- effectiveMappings ---
-  syn java.util.List<MappingDefinition> UpdateDefinition.effectiveMappings();
-  eq ReadFromMqttDefinition.effectiveMappings() {
+  syn java.util.List<MappingDefinition> EndpointDefinition.effectiveMappings();
+  eq ReceiveFromMqttDefinition.effectiveMappings() {
     // if there is a first mapping, check if its input type is byte[].
     //  or if no mappings are specified.
     // then prepend the suitable default mapping
@@ -120,7 +120,7 @@ aspect Mappings {
     }
     return result;
   }
-  eq WriteToMqttDefinition.effectiveMappings() {
+  eq SendToMqttDefinition.effectiveMappings() {
     // if there is a mapping, check if the output type of the last mapping is byte[].
     //  or if no mappings are specified.
     // then append the suitable default mapping
@@ -159,46 +159,46 @@ aspect Mappings {
   eq JavaArrayMappingDefinitionType.isArray() = true;
 
   // --- suitableDefaultMapping ---
-  syn DefaultMappingDefinition UpdateDefinition.suitableDefaultMapping();
-  eq ReadFromMqttDefinition.suitableDefaultMapping() {
+  syn DefaultMappingDefinition EndpointDefinition.suitableDefaultMapping();
+  eq ReceiveFromMqttDefinition.suitableDefaultMapping() {
     String typeName = getMappingList().isEmpty() ?
         getToken().getJavaTypeUse().getName() :
         getMappingList().get(0).getFromType().prettyPrint();
     switch(typeName) {
       case "int":
-      case "Integer": return ros2rag().defaultBytesToIntMapping();
+      case "Integer": return ragconnect().defaultBytesToIntMapping();
       case "short":
-      case "Short": return ros2rag().defaultBytesToShortMapping();
+      case "Short": return ragconnect().defaultBytesToShortMapping();
       case "long":
-      case "Long": return ros2rag().defaultBytesToLongMapping();
+      case "Long": return ragconnect().defaultBytesToLongMapping();
       case "float":
-      case "Float": return ros2rag().defaultBytesToFloatMapping();
+      case "Float": return ragconnect().defaultBytesToFloatMapping();
       case "double":
-      case "Double": return ros2rag().defaultBytesToDoubleMapping();
+      case "Double": return ragconnect().defaultBytesToDoubleMapping();
       case "char":
-      case "Character": return ros2rag().defaultBytesToCharMapping();
-      case "String": return ros2rag().defaultBytesToStringMapping();
+      case "Character": return ragconnect().defaultBytesToCharMapping();
+      case "String": return ragconnect().defaultBytesToStringMapping();
       default: return null;
     }
   }
-  eq WriteToMqttDefinition.suitableDefaultMapping() {
+  eq SendToMqttDefinition.suitableDefaultMapping() {
     String typeName = getMappingList().isEmpty() ?
         getToken().getJavaTypeUse().getName() :
         getMappingList().get(getMappingList().size() - 1).getFromType().prettyPrint();
     switch(typeName) {
       case "int":
-      case "Integer": return ros2rag().defaultIntToBytesMapping();
+      case "Integer": return ragconnect().defaultIntToBytesMapping();
       case "short":
-      case "Short": return ros2rag().defaultShortToBytesMapping();
+      case "Short": return ragconnect().defaultShortToBytesMapping();
       case "long":
-      case "Long": return ros2rag().defaultLongToBytesMapping();
+      case "Long": return ragconnect().defaultLongToBytesMapping();
       case "float":
-      case "Float": return ros2rag().defaultFloatToBytesMapping();
+      case "Float": return ragconnect().defaultFloatToBytesMapping();
       case "double":
-      case "Double": return ros2rag().defaultDoubleToBytesMapping();
+      case "Double": return ragconnect().defaultDoubleToBytesMapping();
       case "char":
-      case "Character": return ros2rag().defaultCharToBytesMapping();
-      case "String": return ros2rag().defaultStringToBytesMapping();
+      case "Character": return ragconnect().defaultCharToBytesMapping();
+      case "String": return ragconnect().defaultStringToBytesMapping();
       default: return null;
     }
   }
@@ -208,7 +208,7 @@ aspect Mappings {
   eq JavaArrayMappingDefinitionType.isByteArray() = getType().getName().equals("byte");
 
   // --- allMappingDefinitions ---
-  syn java.util.List<MappingDefinition> Ros2Rag.allMappingDefinitions() {
+  syn java.util.List<MappingDefinition> RagConnect.allMappingDefinitions() {
     java.util.List<MappingDefinition> result = new java.util.ArrayList<>();
     getMappingDefinitionList().iterator().forEachRemaining(result::add);
     result.add(defaultBytesToIntMapping());
diff --git a/src/main/jastadd/parser/Preamble.parser b/src/main/jastadd/parser/Preamble.parser
index 43fa51e769eed054371cecae2cde354b44e115a3..d701db19d6edb6d6c616bc79fc0145ea59d2713d 100644
--- a/src/main/jastadd/parser/Preamble.parser
+++ b/src/main/jastadd/parser/Preamble.parser
@@ -1,7 +1,7 @@
 %header {:
-package org.jastadd.ros2rag.parser;
-import org.jastadd.ros2rag.ast.*;
+package org.jastadd.ragconnect.parser;
+import org.jastadd.ragconnect.ast.*;
 :};
 
 %goal goal;
-%goal ros2rag;
+%goal ragconnect;
diff --git a/src/main/jastadd/parser/Ros2Rag.parser b/src/main/jastadd/parser/RagConnect.parser
similarity index 70%
rename from src/main/jastadd/parser/Ros2Rag.parser
rename to src/main/jastadd/parser/RagConnect.parser
index 015b4e664950fd9f49601dbea53fc67225c41169..e2685c15555056c64d4f5e8bebdc458ecea981a3 100644
--- a/src/main/jastadd/parser/Ros2Rag.parser
+++ b/src/main/jastadd/parser/RagConnect.parser
@@ -1,9 +1,9 @@
-Ros2Rag ros2rag
-  = update_definition.d ros2rag.r       {: r.getUpdateDefinitionList().insertChild(d, 0); return r; :}
-  | dependency_definition.d ros2rag.r   {: r.getDependencyDefinitionList().insertChild(d, 0); return r; :}
-  | mapping_definition.d ros2rag.r      {: r.getMappingDefinitionList().insertChild(d, 0); return r; :}
-  | comment ros2rag.r                   {: return r; :}
-  |                                     {: return new Ros2Rag(); :}
+RagConnect ragconnect
+  = endpoint_definition.d ragconnect.r       {: r.getEndpointDefinitionList().insertChild(d, 0); return r; :}
+  | dependency_definition.d ragconnect.r   {: r.getDependencyDefinitionList().insertChild(d, 0); return r; :}
+  | mapping_definition.d ragconnect.r      {: r.getMappingDefinitionList().insertChild(d, 0); return r; :}
+  | comment ragconnect.r                   {: return r; :}
+  |                                     {: return new RagConnect(); :}
 ;
 
 %embed {:
@@ -12,31 +12,31 @@ Ros2Rag ros2rag
   }
 :} ;
 
-UpdateDefinition update_definition
-  = READ ID.type_name DOT ID.token_name SCOL
+EndpointDefinition endpoint_definition
+  = RECEIVE ID.type_name DOT ID.token_name SCOL
     {:
-      ReadFromMqttDefinition result = new ReadFromMqttDefinition();
+      ReceiveFromMqttDefinition result = new ReceiveFromMqttDefinition();
       result.setToken(TokenComponent.createRef(type_name + "." + token_name));
       return result;
     :}
-  | READ ID.type_name DOT ID.token_name USING string_list.mapping_defs SCOL
+  | RECEIVE ID.type_name DOT ID.token_name USING string_list.mapping_defs SCOL
     {:
-      ReadFromMqttDefinition result = new ReadFromMqttDefinition();
+      ReceiveFromMqttDefinition result = new ReceiveFromMqttDefinition();
       result.setToken(TokenComponent.createRef(type_name + "." + token_name));
       for (String mapping_def : makeMappingDefs(mapping_defs)) {
         result.addMapping(MappingDefinition.createRef(mapping_def));
       }
       return result;
     :}
-  | WRITE ID.type_name DOT ID.token_name SCOL
+  | SEND ID.type_name DOT ID.token_name SCOL
     {:
-      WriteToMqttDefinition result = new WriteToMqttDefinition();
+      SendToMqttDefinition result = new SendToMqttDefinition();
       result.setToken(TokenComponent.createRef(type_name + "." + token_name));
       return result;
     :}
-  | WRITE ID.type_name DOT ID.token_name USING string_list.mapping_defs SCOL
+  | SEND ID.type_name DOT ID.token_name USING string_list.mapping_defs SCOL
     {:
-      WriteToMqttDefinition result = new WriteToMqttDefinition();
+      SendToMqttDefinition result = new SendToMqttDefinition();
       result.setToken(TokenComponent.createRef(type_name + "." + token_name));
       for (String mapping_def : makeMappingDefs(mapping_defs)) {
         result.addMapping(MappingDefinition.createRef(mapping_def));
diff --git a/src/main/jastadd/scanner/Header.flex b/src/main/jastadd/scanner/Header.flex
index 974aa01fe70d15edbd4c80ac67169a18fe95f9e8..f289a7e89438a572e3dd936548355cf600d3b8bd 100644
--- a/src/main/jastadd/scanner/Header.flex
+++ b/src/main/jastadd/scanner/Header.flex
@@ -1,17 +1,20 @@
-package org.jastadd.ros2rag.scanner;
+package org.jastadd.ragconnect.scanner;
 
-import org.jastadd.ros2rag.parser.Ros2RagParser.Terminals;
+import org.jastadd.ragconnect.parser.RagConnectParser.Terminals;
 %%
 
 %public
 %final
-%class Ros2RagScanner
+%class RagConnectScanner
 %extends beaver.Scanner
 
 %type beaver.Symbol
 %function nextToken
 %yylexthrow beaver.Scanner.Exception
-%scanerror Ros2RagScanner.ScannerError
+%scanerror RagConnectScanner.ScannerError
+
+%x COMMENT
+%s DECLARATION
 
 %line
 %column
diff --git a/src/main/jastadd/scanner/Keywords.flex b/src/main/jastadd/scanner/Keywords.flex
index 3f546823fd8e034f821c8e867d8777ef697effdd..5773118d8fda8ffdc536b504aa7056b8784ddfb3 100644
--- a/src/main/jastadd/scanner/Keywords.flex
+++ b/src/main/jastadd/scanner/Keywords.flex
@@ -1,5 +1,5 @@
-"read"       { return sym(Terminals.READ); }
-"write"      { return sym(Terminals.WRITE); }
+"receive"    { yybegin(DECLARATION); return sym(Terminals.RECEIVE); }
+"send"       { yybegin(DECLARATION); return sym(Terminals.SEND); }
 "using"      { return sym(Terminals.USING); }
 "canDependOn" { return sym(Terminals.CAN_DEPEND_ON); }
 "maps"       { return sym(Terminals.MAPS); }
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/AppendableWriter.java b/src/main/java/org/jastadd/ragconnect/compiler/AppendableWriter.java
similarity index 93%
rename from src/main/java/org/jastadd/ros2rag/compiler/AppendableWriter.java
rename to src/main/java/org/jastadd/ragconnect/compiler/AppendableWriter.java
index 97680b18dc4fd1d8af3df75f35221e059355e19e..55818dcda1c89948726065c9d11640fcb6601130 100644
--- a/src/main/java/org/jastadd/ros2rag/compiler/AppendableWriter.java
+++ b/src/main/java/org/jastadd/ragconnect/compiler/AppendableWriter.java
@@ -1,4 +1,4 @@
-package org.jastadd.ros2rag.compiler;
+package org.jastadd.ragconnect.compiler;
 
 import java.io.IOException;
 import java.io.Writer;
diff --git a/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java b/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b33412c7994b5443088de6249273b9b83374414
--- /dev/null
+++ b/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
@@ -0,0 +1,235 @@
+package org.jastadd.ragconnect.compiler;
+
+import beaver.Parser;
+import org.jastadd.option.BooleanOption;
+import org.jastadd.option.ValueOption;
+import org.jastadd.relast.compiler.AbstractCompiler;
+import org.jastadd.relast.compiler.CompilerException;
+import org.jastadd.ragconnect.ast.*;
+import org.jastadd.ragconnect.parser.RagConnectParser;
+import org.jastadd.ragconnect.scanner.RagConnectScanner;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Collection;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Compiler extends AbstractCompiler {
+
+//  private ValueOption optionOutputDir;
+  private ValueOption optionRootNode;
+  private BooleanOption optionVerbose;
+  private BooleanOption optionLogReads;
+  private BooleanOption optionLogWrites;
+
+  public Compiler() {
+    super("ragconnect", true);
+  }
+
+  @Override
+  protected int compile() throws CompilerException {
+    if (getConfiguration().shouldPrintVersion()) {
+      System.out.println(readVersion());
+      return 0;
+    }
+    if (getConfiguration().shouldPrintHelp()) {
+      getConfiguration().printHelp(System.out);
+      return 0;
+    }
+
+    printMessage("Running RagConnect " + readVersion());
+
+    if (!getConfiguration().outputDir().exists()) {
+      try {
+        Files.createDirectories(getConfiguration().outputDir().toPath());
+      } catch (IOException e) {
+        throw new CompilerException("Error creating output dir " + getConfiguration().outputDir(), e);
+      }
+    }
+
+    RagConnect ragConnect = parseProgram(getConfiguration().getFiles());
+
+    if (!ragConnect.errors().isEmpty()) {
+      System.err.println("Errors:");
+      for (ErrorMessage e : ragConnect.errors()) {
+        System.err.println(e);
+      }
+      System.exit(1);
+    }
+
+    printMessage("Writing output files");
+    // copy MqttHandler into outputDir
+    final String mqttHandlerFileName = "MqttHandler.jadd";
+    try {
+      InputStream inputStream = Compiler.class.getClassLoader().getResourceAsStream(mqttHandlerFileName);
+      if (inputStream == null) {
+        throw new CompilerException("Could not open " + mqttHandlerFileName);
+      }
+      Files.copy(inputStream,
+          getConfiguration().outputDir().toPath().resolve(mqttHandlerFileName),
+          StandardCopyOption.REPLACE_EXISTING);
+    } catch (IOException e) {
+      throw new CompilerException("Could not copy " + mqttHandlerFileName, e);
+    }
+    for (GrammarFile grammarFile : ragConnect.getProgram().getGrammarFileList()) {
+      Path outputFile = getConfiguration().outputDir().toPath().resolve(grammarFile.getFileName());
+      sendToFile(outputFile, grammarFile.generateAbstractGrammar());
+    }
+    sendToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.jadd"), ragConnect.generateAspect(optionRootNode.value()));
+    return 0;
+  }
+
+  public static void main(String[] args) {
+    System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
+    System.setProperty("mustache.debug", "true");
+    try {
+      new Compiler().run(args);
+    } catch (CompilerException e) {
+      System.err.println(e.getMessage());
+      System.exit(-1);
+    }
+  }
+
+  /**
+   * Reads the version string.
+   *
+   * The version string is read from the property file
+   * src/main/resources/Version.properties. This
+   * file should be generated during the build process. If it is missing
+   * then there is some problem in the build script.
+   *
+   * @author Jesper Öqvist <jesper.oqvist@cs.lth.se>
+   * @return the read version string, or <code>version ?</code>
+   */
+  private String readVersion() {
+    try {
+      ResourceBundle resources = ResourceBundle.getBundle("ragConnectVersion");
+      return resources.getString("version");
+    } catch (MissingResourceException e) {
+      return "version ?";
+    }
+  }
+
+  private void printMessage(String message) {
+    System.out.println(message);
+  }
+
+  private void sendToFile(Path path, String str) throws CompilerException {
+    try (BufferedWriter writer = Files.newBufferedWriter(path)) {
+      writer.append(str);
+    } catch (Exception e) {
+      throw new CompilerException("Could not write to file " + path.toAbsolutePath(), e);
+    }
+  }
+
+  protected void initOptions() {
+    super.initOptions();
+    optionRootNode = addOption(
+        new ValueOption("rootNode", "root node in the base grammar.")
+        .acceptAnyValue()
+        .needsValue(true));
+    optionVerbose = addOption(
+        new BooleanOption("verbose", "Print more messages while compiling.")
+        .defaultValue(false));
+    optionLogReads = addOption(
+        new BooleanOption("logReads", "Enable logging for every read.")
+        .defaultValue(false));
+    optionLogWrites = addOption(
+        new BooleanOption("logWrites", "Enable logging for every write.")
+        .defaultValue(false));
+  }
+
+  private RagConnect parseProgram(Collection<String> files) throws CompilerException {
+    Program program = new Program();
+
+    RagConnect ragConnect = new RagConnect();
+    ragConnect.setProgram(program);
+
+    GrammarFile ragConnectGrammarPart = new GrammarFile();
+    ragConnectGrammarPart.setFileName("RagConnect.relast");
+    program.addGrammarFile(ragConnectGrammarPart);
+
+    for (String filename : files) {
+      String extension = filename.substring(filename.lastIndexOf('.') + 1);
+      switch (extension) {
+        case "ast":
+        case "relast":
+          // processGrammar
+          parseGrammar(program, filename);
+          break;
+        case "connect":
+          // process ragConnect
+          RagConnect parsedRagConnect = parseRagConnect(program, filename);
+          mergeRagConnectDefinitions(ragConnect, parsedRagConnect);
+          break;
+        default:
+          throw new CompilerException("Unknown file extension in " + filename);
+      }
+    }
+    ragConnect.treeResolveAll();
+    ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
+    ASTNode.loggingEnabledForReads = optionLogReads.value();
+    ASTNode.loggingEnabledForWrites = optionLogWrites.value();
+    return ragConnect;
+  }
+
+  private void parseGrammar(Program program, String filename) throws CompilerException {
+    try (BufferedReader reader = Files.newBufferedReader(Paths.get(filename))) {
+      RagConnectScanner scanner = new RagConnectScanner(reader);
+      RagConnectParser parser = new RagConnectParser();
+      GrammarFile grammarFile = (GrammarFile) parser.parse(scanner);
+      if (optionVerbose.value()) {
+        grammarFile.dumpTree(System.out);
+      }
+      program.addGrammarFile(grammarFile);
+      grammarFile.treeResolveAll();
+      grammarFile.setFileName(toBaseName(filename));
+    } catch (IOException | Parser.Exception e) {
+      throw new CompilerException("Could not parse grammar file " + filename, e);
+    }
+  }
+
+  private RagConnect parseRagConnect(Program program, String filename) throws CompilerException {
+    try (BufferedReader reader = Files.newBufferedReader(Paths.get(filename))) {
+      RagConnectScanner scanner = new RagConnectScanner(reader);
+      RagConnectParser parser = new RagConnectParser();
+      RagConnect ragConnect = (RagConnect) parser.parse(scanner, RagConnectParser.AltGoals.ragconnect);
+      ragConnect.setProgram(program);
+      ragConnect.setFileName(toBaseName(filename));
+      return ragConnect;
+    } catch (IOException | Parser.Exception e) {
+      throw new CompilerException("Could not parse connect file " + filename, e);
+    }
+  }
+
+  /**
+   * Extracts the basename of the given file, with file extension
+   * @param filename the given filename
+   * @return the basename
+   */
+  private String toBaseName(String filename) {
+    return new File(filename).getName();
+  }
+
+  private void mergeRagConnectDefinitions(RagConnect ragConnect, RagConnect ragConnectToIntegrate) {
+    for (EndpointDefinition endpointDefinition : ragConnectToIntegrate.getEndpointDefinitionList()) {
+      ragConnect.addEndpointDefinition(endpointDefinition);
+    }
+    for (MappingDefinition mappingDefinition : ragConnectToIntegrate.getMappingDefinitionList()) {
+      ragConnect.addMappingDefinition(mappingDefinition);
+    }
+    for (DependencyDefinition dependencyDefinition : ragConnectToIntegrate.getDependencyDefinitionList()) {
+      ragConnect.addDependencyDefinition(dependencyDefinition);
+    }
+  }
+
+//  protected void printUsage() {
+//    System.out.println("Usage: java -jar ragconnect.jar [--option1] [--option2=value] ...  <filename1> <filename2> ... ");
+//    System.out.println("Options:");
+//    System.out.print(commandLine.printOptionHelp());
+//  }
+}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/SimpleMain.java b/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java
similarity index 75%
rename from src/main/java/org/jastadd/ros2rag/compiler/SimpleMain.java
rename to src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java
index 74406f87a166732efedafbc772d114185f24e227..ac1109fef423ed58ebbbdfcaeacbdca42745e341 100644
--- a/src/main/java/org/jastadd/ros2rag/compiler/SimpleMain.java
+++ b/src/main/java/org/jastadd/ragconnect/compiler/SimpleMain.java
@@ -1,9 +1,9 @@
-package org.jastadd.ros2rag.compiler;
+package org.jastadd.ragconnect.compiler;
 
 import beaver.Parser;
-import org.jastadd.ros2rag.ast.*;
-import org.jastadd.ros2rag.parser.Ros2RagParser;
-import org.jastadd.ros2rag.scanner.Ros2RagScanner;
+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;
@@ -102,18 +102,18 @@ public class SimpleMain {
   }
 
   public static void main(String[] args) {
-    testing();
-//    createManualAST();
+//    testing();
+    createManualAST();
   }
 
   private static void createManualAST() {
-    Ros2Rag model = new Ros2Rag();
-    Program program = parseProgram(Paths.get("src", "test", "resources", "Example.relast"));
+    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("PBPose"));
+    mappingDefinition.setFromType(makeMappingDefinitionType("int"));
     mappingDefinition.setFromVariableName("x");
     mappingDefinition.setToType(makeMappingDefinitionType("Position"));
     mappingDefinition.setContent("      pose.position.x += sqrt(.5 * size.x)\n" +
@@ -123,13 +123,16 @@ public class SimpleMain {
         "    ;");
     model.addMappingDefinition(mappingDefinition);
 
-    ReadFromMqttDefinition readFromMqttDefinition = new ReadFromMqttDefinition();
-    readFromMqttDefinition.setAlwaysApply(false);
-    readFromMqttDefinition.setToken(TokenComponent.createRef("Joint.CurrentPosition"));
-    readFromMqttDefinition.addMapping(mappingDefinition);
-    model.addUpdateDefinition(readFromMqttDefinition);
+    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"));
   }
@@ -142,9 +145,12 @@ public class SimpleMain {
 
   private static Program parseProgram(Path path) {
     try (BufferedReader reader = Files.newBufferedReader(path)) {
-      Ros2RagScanner scanner = new Ros2RagScanner(reader);
-      Ros2RagParser parser = new Ros2RagParser();
-      return (Program) parser.parse(scanner);
+      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();
     }
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/Utils.java b/src/main/java/org/jastadd/ragconnect/compiler/Utils.java
similarity index 90%
rename from src/main/java/org/jastadd/ros2rag/compiler/Utils.java
rename to src/main/java/org/jastadd/ragconnect/compiler/Utils.java
index 6a229cd7e9a2551578a87f1c7b5fcccfebd31ff7..c083fe1d912fa74cb4461fce5fcb839f5b88a40f 100644
--- a/src/main/java/org/jastadd/ros2rag/compiler/Utils.java
+++ b/src/main/java/org/jastadd/ragconnect/compiler/Utils.java
@@ -1,4 +1,4 @@
-package org.jastadd.ros2rag.compiler;
+package org.jastadd.ragconnect.compiler;
 
 import java.util.*;
 import java.util.function.Predicate;
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java b/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java
deleted file mode 100644
index b6331130a7b338ef1bf37f6ac372d612cb1754f1..0000000000000000000000000000000000000000
--- a/src/main/java/org/jastadd/ros2rag/compiler/Compiler.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package org.jastadd.ros2rag.compiler;
-
-import beaver.Parser;
-import org.jastadd.ros2rag.ast.*;
-import org.jastadd.ros2rag.compiler.options.CommandLine;
-import org.jastadd.ros2rag.compiler.options.CommandLine.CommandLineException;
-import org.jastadd.ros2rag.compiler.options.FlagOption;
-import org.jastadd.ros2rag.compiler.options.Option;
-import org.jastadd.ros2rag.compiler.options.StringOption;
-import org.jastadd.ros2rag.parser.Ros2RagParser;
-import org.jastadd.ros2rag.scanner.Ros2RagScanner;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Compiler {
-
-  private StringOption optionOutputDir;
-  private StringOption optionInputGrammar;
-  private StringOption optionRootNode;
-  private StringOption optionInputRos2Rag;
-  private FlagOption optionHelp;
-  private FlagOption optionVerbose;
-  private FlagOption optionLogReads;
-  private FlagOption optionLogWrites;
-
-  private ArrayList<Option<?>> options;
-  private CommandLine commandLine;
-
-  public Compiler() {
-    options = new ArrayList<>();
-    addOptions();
-  }
-
-  public void run(String[] args) throws CommandLineException, CompilerException {
-    System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
-    System.setProperty("mustache.debug", "true");
-    options = new ArrayList<>();
-    addOptions();
-    commandLine = new CommandLine(options);
-    commandLine.parse(args);
-
-    if (optionHelp.isSet()) {
-      printUsage();
-      return;
-    }
-
-    if (optionVerbose.isSet()) {
-      try {
-        run();
-      } catch (CompilerException e) {
-        e.printStackTrace();
-        throw e;
-      }
-    } else {
-      run();
-    }
-  }
-
-  private void run() throws CompilerException {
-    String outputDir;
-    if (optionOutputDir.isSet()) {
-      outputDir = optionOutputDir.getValue();
-    } else {
-      outputDir = "gen";
-      System.out.println("No output output dir is set. Assuming '" + outputDir + "'.");
-    }
-    try {
-      Files.createDirectories(Paths.get(outputDir));
-    } catch (IOException e) {
-      throw new CompilerException("Error creating output dir " + outputDir, e);
-    }
-
-    printMessage("Running Ros2Rag Preprocessor");
-
-    if (anyRequiredOptionIsUnset()) {
-      throw new CompilerException("Aborting due to missing values for required options.");
-    }
-
-    List<String> otherArgs = commandLine.getArguments();
-    if (!otherArgs.isEmpty()) {
-      printMessage("Superfluous arguments will be ignored: " + otherArgs);
-    }
-    Ros2Rag ros2Rag = parseProgram(optionInputGrammar.getValue(), optionInputRos2Rag.getValue());
-
-    if (!ros2Rag.errors().isEmpty()) {
-      System.err.println("Errors:");
-      for (ErrorMessage e : ros2Rag.errors()) {
-        System.err.println(e);
-      }
-      System.exit(1);
-    }
-
-    printMessage("Writing output files");
-    // copy MqttHandler into outputDir
-    final String mqttHandlerFileName = "MqttHandler.jadd";
-    try {
-      InputStream inputStream = Compiler.class.getClassLoader().getResourceAsStream(mqttHandlerFileName);
-      if (inputStream == null) {
-        throw new CompilerException("Could not open " + mqttHandlerFileName);
-      }
-      Files.copy(inputStream,
-          Paths.get(outputDir, mqttHandlerFileName),
-          StandardCopyOption.REPLACE_EXISTING);
-    } catch (IOException e) {
-      throw new CompilerException("Could not copy " + mqttHandlerFileName, e);
-    }
-    writeToFile(outputDir + "/Grammar.relast", ros2Rag.getProgram().generateAbstractGrammar());
-    writeToFile(outputDir + "/ROS2RAG.jadd", ros2Rag.generateAspect(optionRootNode.getValue()));
-  }
-
-  private boolean anyRequiredOptionIsUnset() {
-    boolean foundError = false;
-    for (Option<?> option : options) {
-      if (option.hasArgument() == Option.HasArgument.YES && !option.isSet()) {
-        System.err.println("Option '" + option.getName() +
-            "' (" + option.getDescription() + ") is required but unset!");
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-
-  public static void main(String[] args) {
-    try {
-      new Compiler().run(args);
-    } catch (CommandLineException | CompilerException e) {
-      System.err.println(e.getMessage());
-      System.exit(-1);
-    }
-  }
-
-  private void printMessage(String message) {
-    System.out.println(message);
-  }
-
-  private void writeToFile(String filename, String str) throws CompilerException {
-    try {
-      PrintWriter writer = new PrintWriter(filename);
-      writer.print(str);
-      writer.close();
-    } catch (Exception e) {
-      throw new CompilerException("Could not write to file " + filename, e);
-    }
-  }
-
-  private void addOptions() {
-    optionOutputDir = addOption(new StringOption("outputDir", "target directory for the generated files."));
-    optionInputGrammar = addOption(new StringOption("inputGrammar", "base grammar."));
-    optionRootNode = addOption(new StringOption("rootNode", "root node in the base grammar."));
-    optionInputRos2Rag = addOption(new StringOption("inputRos2Rag", "ros2rag definition file."));
-    optionHelp = addOption(new FlagOption("help", "Print usage and exit."));
-    optionVerbose = addOption(new FlagOption("verbose", "Print more messages while compiling."));
-    optionLogReads = addOption(new FlagOption("logReads", "Enable logging for every read."));
-    optionLogWrites = addOption(new FlagOption("logWrites", "Enable logging for every write."));
-  }
-
-  private <OptionType extends Option<?>> OptionType addOption(OptionType option) {
-    options.add(option);
-    return option;
-  }
-
-  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();
-      inputGrammar = (GrammarFile) parser.parse(scanner);
-      if (optionVerbose.isSet()) {
-        inputGrammar.dumpTree(System.out);
-      }
-      program.addGrammarFile(inputGrammar);
-      inputGrammar.treeResolveAll();
-      inputGrammar.setFileName(inputGrammarFileName);
-    } catch (IOException | Parser.Exception e) {
-      throw new CompilerException("Could not parse grammar file " + inputGrammarFileName, e);
-    }
-
-    try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputRos2RagFileName))) {
-      Ros2RagScanner scanner = new Ros2RagScanner(reader);
-      Ros2RagParser parser = new Ros2RagParser();
-      ros2Rag = (Ros2Rag) parser.parse(scanner, Ros2RagParser.AltGoals.ros2rag);
-      ros2Rag.setProgram(program);
-      ros2Rag.setFileName(inputRos2RagFileName);
-    } catch (IOException | Parser.Exception e) {
-      throw new CompilerException("Could not parse ros2rag file " + inputRos2RagFileName, e);
-    }
-    ros2Rag.treeResolveAll();
-    ros2Rag.additionalRelations().forEach(inputGrammar::addDeclaration);
-    ASTNode.loggingEnabledForReads = optionLogReads.isSet();
-    ASTNode.loggingEnabledForWrites = optionLogWrites.isSet();
-    return ros2Rag;
-  }
-
-  protected void printUsage() {
-    System.out.println("Usage: java -jar ros2rag.jar [--option1] [--option2=value] ...  <filename1> <filename2> ... ");
-    System.out.println("Options:");
-    System.out.print(commandLine.printOptionHelp());
-  }
-
-  public static class CompilerException extends Exception {
-    CompilerException(String message) {
-      super(message);
-    }
-    CompilerException(String message, Throwable cause) {
-      super(message, cause);
-    }
-  }
-}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/options/CommandLine.java b/src/main/java/org/jastadd/ros2rag/compiler/options/CommandLine.java
deleted file mode 100644
index 89a1335c5440cc88fc8ee7c0c22552fffd86c13b..0000000000000000000000000000000000000000
--- a/src/main/java/org/jastadd/ros2rag/compiler/options/CommandLine.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.jastadd.ros2rag.compiler.options;
-
-import java.util.*;
-
-public class CommandLine {
-  private final Collection<Option<?>> options;
-  private final Map<String, Option<?>> mapping;
-  private final List<String> arguments;
-
-  public CommandLine(Collection<Option<?>> options) {
-    this.options = options;
-    this.mapping = new HashMap<>();
-    for (Option<?> option : options) {
-      mapping.put(option.getName(), option);
-    }
-    this.arguments = new ArrayList<>();
-  }
-
-  public void parse(String[] args) throws CommandLineException {
-    int i = 0;
-    while (i < args.length) {
-      if (args[i].startsWith(Option.PREFIX)) {
-        int argumentIndex = args[i].indexOf("=");
-        String name;
-        String argument = null;
-        if (argumentIndex > 0) {
-          name = args[i].substring(2, argumentIndex);
-          argument = args[i].substring(argumentIndex + 1);
-        } else {
-          name = args[i].substring(2);
-        }
-        Option<?> option = mapping.get(name);
-        if (option == null) {
-          throw new CommandLineException("Option " + Option.PREFIX + name + " not found");
-        }
-        match(option, argument);
-      } else {
-        arguments.add(args[i]);
-      }
-      i++;
-    }
-  }
-
-  public void match(Option<?> option, String argument) throws CommandLineException {
-    try {
-      switch (option.hasArgument()) {
-        case NO:
-          if (argument == null) {
-            option.match(null);
-          } else {
-            throw new CommandLineException("Option " + option + " is not allowed to have an argument");
-          }
-          break;
-        case OPTIONAL:
-          option.match(argument);
-          break;
-        case YES:
-          if (argument != null) {
-            option.match(argument);
-          } else {
-            throw new CommandLineException("Option " + option + " requires an argument");
-          }
-          break;
-      }
-    } catch (Option.IllegalMatchException e) {
-      throw new CommandLineException("Invalid value for option " + option + ": " + e.getMessage());
-    }
-  }
-
-  public List<String> getArguments() {
-    return arguments;
-  }
-
-  public String printOptionHelp() {
-    StringBuilder sb = new StringBuilder();
-    int longestOption = 0;
-    for (Option<?> option : options) {
-      if (longestOption < option.getName().length()) {
-        longestOption = option.getName().length();
-      }
-    }
-    for (Option<?> option : new TreeSet<>(options)) {
-      String s = String.format("  %s%-" + (longestOption + 6) + "s %s%n",
-          Option.PREFIX, option.getName(), option.getDescription());
-      sb.append(s);
-    }
-    return sb.toString();
-  }
-
-  public static class CommandLineException extends Exception {
-    private static final long serialVersionUID = 1L;
-
-    public CommandLineException(String message) {
-      super(message);
-    }
-  }
-}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/options/EnumOption.java b/src/main/java/org/jastadd/ros2rag/compiler/options/EnumOption.java
deleted file mode 100644
index 67ada98e8c2483b8d29ffeb73f99e4be8e6244c8..0000000000000000000000000000000000000000
--- a/src/main/java/org/jastadd/ros2rag/compiler/options/EnumOption.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.jastadd.ros2rag.compiler.options;
-
-import java.util.Collection;
-import java.util.TreeSet;
-
-public class EnumOption extends Option<String> {
-  private final TreeSet<String> allowedValues;
-  private final String defaultValue;
-  private String value;
-  private boolean isSet;
-
-  public EnumOption(String name, String description, Collection<String> allowedValues, String defaultValue) {
-    super(name, description);
-    this.allowedValues = new TreeSet<>(allowedValues);
-    this.defaultValue = defaultValue;
-    this.value = defaultValue;
-    this.isSet = false;
-  }
-
-  public boolean addAllowedValue(String allowedValue) {
-    return allowedValues.add(allowedValue);
-  }
-
-  @Override
-  public String getValue() {
-    return value;
-  }
-
-  @Override
-  public Option.HasArgument hasArgument() {
-    return Option.HasArgument.OPTIONAL;
-  }
-
-  @Override
-  public void match(String argument) throws IllegalMatchException {
-    if (argument == null) {
-      isSet = true;
-      value = defaultValue;
-    } else if (allowedValues.contains(argument)) {
-      isSet = true;
-      value = argument;
-    } else {
-      throw new IllegalMatchException(argument
-          + " is not allowed, allowed values are " + allowedValues);
-    }
-  }
-
-  @Override
-  public boolean isSet() {
-    return isSet;
-  }
-
-  @Override
-  public String getDescription() {
-    String allowedValuesStr = allowedValues.toString();
-    allowedValuesStr = allowedValuesStr.substring(1);
-    allowedValuesStr = allowedValuesStr.substring(0, allowedValuesStr.length() - 1);
-    return super.getDescription() + " (allowed values: " + allowedValuesStr + ")";
-  }
-}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/options/FlagOption.java b/src/main/java/org/jastadd/ros2rag/compiler/options/FlagOption.java
deleted file mode 100644
index ad87ed19e91b03f05d163f0cc123af15a4a4e2e2..0000000000000000000000000000000000000000
--- a/src/main/java/org/jastadd/ros2rag/compiler/options/FlagOption.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.jastadd.ros2rag.compiler.options;
-
-public class FlagOption extends Option<Boolean> {
-  private boolean value;
-
-  public FlagOption(String name, String description) {
-    super(name, description);
-    value = false;
-  }
-
-  @Override
-  public Boolean getValue() {
-    return value;
-  }
-
-  @Override
-  public Option.HasArgument hasArgument() {
-    return Option.HasArgument.NO;
-  }
-
-  @Override
-  public void match(String string) throws IllegalMatchException {
-    value = true;
-  }
-
-  @Override
-  public boolean isSet() {
-    return getValue();
-  }
-}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/options/Option.java b/src/main/java/org/jastadd/ros2rag/compiler/options/Option.java
deleted file mode 100644
index 0f57f9899ba5f28ee80ca6d37788a6e31123ac47..0000000000000000000000000000000000000000
--- a/src/main/java/org/jastadd/ros2rag/compiler/options/Option.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.jastadd.ros2rag.compiler.options;
-
-abstract public class Option<ValueType> implements Comparable<Option<?>> {
-  public final static String PREFIX = "--";
-  private final String name;
-  private final String description;
-
-  public Option(String name, String description) {
-    this.name = name;
-    this.description = description;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public String getDescription() {
-    return description;
-  }
-
-  @Override
-  public int compareTo(Option<?> o) {
-    return name.compareTo(o.name);
-  }
-
-  @Override
-  public boolean equals(Object other) {
-    if (other instanceof Option) {
-      return compareTo((Option<?>) other) == 0;
-    }
-    return false;
-  }
-
-  @Override
-  public String toString() {
-    return PREFIX + name;
-  }
-
-  abstract public boolean isSet();
-
-  abstract public ValueType getValue();
-
-  abstract public HasArgument hasArgument();
-
-  abstract public void match(String input) throws IllegalMatchException;
-
-  public enum HasArgument {
-    NO,
-    OPTIONAL,
-    YES
-  }
-
-  public static class IllegalMatchException extends Exception {
-    private static final long serialVersionUID = 1L;
-
-    public IllegalMatchException(String message) {
-      super(message);
-    }
-  }
-}
diff --git a/src/main/java/org/jastadd/ros2rag/compiler/options/StringOption.java b/src/main/java/org/jastadd/ros2rag/compiler/options/StringOption.java
deleted file mode 100644
index 19082b5ae6b9fa90145a73ff4ddc4b58b2f9b122..0000000000000000000000000000000000000000
--- a/src/main/java/org/jastadd/ros2rag/compiler/options/StringOption.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.jastadd.ros2rag.compiler.options;
-
-public class StringOption extends Option<String> {
-  private String value;
-  private boolean isSet;
-
-  public StringOption(String name, String description) {
-    this(name, description, "");
-  }
-
-  public StringOption(String name, String description, String defaultValue) {
-    super(name, description);
-    value = defaultValue;
-    isSet = false;
-  }
-
-  @Override
-  public String getValue() {
-    return value;
-  }
-
-  @Override
-  public Option.HasArgument hasArgument() {
-    return Option.HasArgument.YES;
-  }
-
-  @Override
-  public void match(String value) {
-    this.value = value;
-    isSet = true;
-  }
-
-  @Override
-  public boolean isSet() {
-    return isSet;
-  }
-}
diff --git a/src/main/resources/MqttHandler.jadd b/src/main/resources/MqttHandler.jadd
index c3e98dc89377e6217946fafa54a9eb7ab7594c61..493d8e4452e81c5dbfa45a522a6366345908cdcc 100644
--- a/src/main/resources/MqttHandler.jadd
+++ b/src/main/resources/MqttHandler.jadd
@@ -24,7 +24,7 @@ public class MqttHandler {
   private final java.util.Map<String, java.util.List<java.util.function.Consumer<byte[]>>> callbacks;
 
   public MqttHandler() {
-    this("Ros2Rag");
+    this("RagConnect");
   }
 
   public MqttHandler(String name) {
diff --git a/src/main/resources/mqtt.mustache b/src/main/resources/mqtt.mustache
index d65ca944a9dc7e881ff75d89ea696d4bb1fe09fc..dbdb85e7954dbf50ae7e150ffc43dd4cbda0fd80 100644
--- a/src/main/resources/mqtt.mustache
+++ b/src/main/resources/mqtt.mustache
@@ -16,8 +16,8 @@ aspect MQTT {
     {{mqttHandlerField}}.close();
   }
 
-  inh MqttHandler ASTNode.{{mqttHandlerAttribute}}();
   {{#getRootTypeComponents}}
+  {{#first}}inh MqttHandler ASTNode.{{mqttHandlerAttribute}}();{{/first}}
   eq {{rootNodeName}}.get{{name}}().{{mqttHandlerAttribute}}() = {{mqttHandlerField}};
   {{/getRootTypeComponents}}
 }
diff --git a/src/main/resources/ragConnectVersion.properties b/src/main/resources/ragConnectVersion.properties
new file mode 100644
index 0000000000000000000000000000000000000000..8ec441610d66cd3f793075302676eb132eea35c3
--- /dev/null
+++ b/src/main/resources/ragConnectVersion.properties
@@ -0,0 +1,2 @@
+#Wed Jul 29 16:29:05 CEST 2020
+version=0.2.0
diff --git a/src/main/resources/ros2rag.mustache b/src/main/resources/ragconnect.mustache
similarity index 64%
rename from src/main/resources/ros2rag.mustache
rename to src/main/resources/ragconnect.mustache
index dd5e73cf554e35cc20da014b2d83f0db1b88521b..0b455283977cf812a47b5266ee593c6597e97cc9 100644
--- a/src/main/resources/ros2rag.mustache
+++ b/src/main/resources/ragconnect.mustache
@@ -1,12 +1,12 @@
 {{> mqtt}}
 aspect ROS2RAG {
-  {{#ReadDefinitions}}
-    {{> readDefinition}}
-  {{/ReadDefinitions}}
+  {{#ReceiveDefinitions}}
+    {{> receiveDefinition}}
+  {{/ReceiveDefinitions}}
 
-  {{#WriteDefinitions}}
-    {{> writeDefinition}}
-  {{/WriteDefinitions}}
+  {{#SendDefinitions}}
+    {{> sendDefinition}}
+  {{/SendDefinitions}}
 
   {{#MappingDefinitions}}
     {{> mappingDefinition}}
diff --git a/src/main/resources/readDefinition.mustache b/src/main/resources/receiveDefinition.mustache
similarity index 68%
rename from src/main/resources/readDefinition.mustache
rename to src/main/resources/receiveDefinition.mustache
index 77235a277f5acdfee6c07dedf62e6bfa4e090055..e2df0433fe82b37df2c016887da52a11cfd2692b 100644
--- a/src/main/resources/readDefinition.mustache
+++ b/src/main/resources/receiveDefinition.mustache
@@ -2,7 +2,7 @@
     {{mqttHandlerAttribute}}().newConnection(topic, message -> {
       {{> mappingApplication}}
       {{#loggingEnabledForReads}}
-      System.out.println("[Read] " + topic + " -> {{tokenName}} = " + {{lastResult}});{{!lastResult has to be a new attribute}}
+      System.out.println("[Receive] " + topic + " -> {{tokenName}} = " + {{lastResult}});{{!lastResult has to be a new attribute}}
       {{/loggingEnabledForReads}}
       set{{tokenName}}({{lastResult}});
     });
diff --git a/src/main/resources/writeDefinition.mustache b/src/main/resources/sendDefinition.mustache
similarity index 67%
rename from src/main/resources/writeDefinition.mustache
rename to src/main/resources/sendDefinition.mustache
index 6e2e18476424269bc10e9e03ccfdd6444ff55762..477dbc550132af842e53e8fed2cbbee0c8996296 100644
--- a/src/main/resources/writeDefinition.mustache
+++ b/src/main/resources/sendDefinition.mustache
@@ -1,8 +1,8 @@
-  private String {{parentTypeName}}.{{writeTopic}} = null;
+  private String {{parentTypeName}}.{{sendTopic}} = null;
   private byte[] {{parentTypeName}}.{{lastValue}} = null;
 
   public void {{parentTypeName}}.{{connectMethod}}(String topic, boolean writeCurrentValue) {
-    {{writeTopic}} = topic;
+    {{sendTopic}} = topic;
     {{updateMethod}}();
     if (writeCurrentValue) {
       {{writeMethod}}();
@@ -18,7 +18,7 @@
 
   protected void {{parentTypeName}}.{{writeMethod}}() {
     {{#loggingEnabledForWrites}}
-    System.out.println("[Write] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{writeTopic}});
+    System.out.println("[Send] {{tokenName}} = " + get{{tokenName}}() + " -> " + {{sendTopic}});
     {{/loggingEnabledForWrites}}
-    {{mqttHandlerAttribute}}().publish({{writeTopic}}, {{lastValue}});
+    {{mqttHandlerAttribute}}().publish({{sendTopic}}, {{lastValue}});
   }
diff --git a/src/main/resources/tokenComponent.mustache b/src/main/resources/tokenComponent.mustache
index a3615c4526e5725bdd49121b16a87a011562f0cd..e6a136d1c8de08b6dce9104fd46fafa5d91b67b6 100644
--- a/src/main/resources/tokenComponent.mustache
+++ b/src/main/resources/tokenComponent.mustache
@@ -2,11 +2,11 @@
     set{{internalName}}(value);
     {{#DependencyDefinitions}}
     for ({{targetParentTypeName}} target : get{{internalRelationPrefix}}TargetList()) {
-      {{#targetUpdateDefinition}}
+      {{#targetEndpointDefinition}}
       if (target.{{updateMethod}}()) {
         target.{{writeMethod}}();
       }
-      {{/targetUpdateDefinition}}
+      {{/targetEndpointDefinition}}
     }
     {{/DependencyDefinitions}}
     return this;