diff --git a/ragconnect.base/src/main/jastadd/Analysis.jrag b/ragconnect.base/src/main/jastadd/Analysis.jrag
index ac891b0e819b1e57e135afced64495a76396db5e..88d2ffa1a6428c7128f8dfecfca9dd5544dee17f 100644
--- a/ragconnect.base/src/main/jastadd/Analysis.jrag
+++ b/ragconnect.base/src/main/jastadd/Analysis.jrag
@@ -1,25 +1,27 @@
 aspect Analysis {
   // --- lookupTokenEndpointDefinition ---
-  inh java.util.List<TokenEndpointDefinition> TokenEndpointDefinition.lookupTokenEndpointDefinitions(TokenComponent token);
+  inh java.util.List<EndpointDefinition> EndpointDefinition.lookupTokenEndpointDefinitions(TokenComponent token);
+  inh java.util.List<EndpointDefinition> EndpointTarget.lookupTokenEndpointDefinitions(TokenComponent token);
   eq RagConnect.getConnectSpecificationFile().lookupTokenEndpointDefinitions(TokenComponent token) = lookupTokenEndpointDefinitions(token);
-  syn java.util.List<TokenEndpointDefinition> RagConnect.lookupTokenEndpointDefinitions(TokenComponent token) {
-    java.util.List<TokenEndpointDefinition> result = new java.util.ArrayList<>();
-    for (EndpointDefinition def : allEndpointDefinitionList()) {
-      if (def.isTokenEndpointDefinition() && def.asTokenEndpointDefinition().getToken().equals(token)) {
-        result.add(def.asTokenEndpointDefinition());
+  syn java.util.List<EndpointDefinition> RagConnect.lookupTokenEndpointDefinitions(TokenComponent token) {
+    java.util.List<EndpointDefinition> result = new java.util.ArrayList<>();
+    for (EndpointTarget target : allEndpointTargetList()) {
+      if (target.isTokenEndpointTarget() && target.asTokenEndpointTarget().getToken().equals(token)) {
+        result.add(target.containingEndpointDefinition());
       }
     }
     return result;
   }
 
   // --- lookupTypeEndpointDefinition ---
-  inh java.util.List<TypeEndpointDefinition> TypeEndpointDefinition.lookupTypeEndpointDefinitions(TypeComponent type);
+  inh java.util.List<EndpointDefinition> EndpointDefinition.lookupTypeEndpointDefinitions(TypeComponent type);
+  inh java.util.List<EndpointDefinition> EndpointTarget.lookupTypeEndpointDefinitions(TypeComponent type);
   eq RagConnect.getConnectSpecificationFile().lookupTypeEndpointDefinitions(TypeComponent type) = lookupTypeEndpointDefinitions(type);
-  syn java.util.List<TypeEndpointDefinition> RagConnect.lookupTypeEndpointDefinitions(TypeComponent type) {
-    java.util.List<TypeEndpointDefinition> result = new java.util.ArrayList<>();
-    for (EndpointDefinition def : allEndpointDefinitionList()) {
-      if (def.isTypeEndpointDefinition() && def.asTypeEndpointDefinition().getType().equals(type)) {
-        result.add(def.asTypeEndpointDefinition());
+  syn java.util.List<EndpointDefinition> RagConnect.lookupTypeEndpointDefinitions(TypeComponent type) {
+    java.util.List<EndpointDefinition> result = new java.util.ArrayList<>();
+    for (EndpointTarget target : allEndpointTargetList()) {
+      if (target.isTypeEndpointTarget() && target.asTypeEndpointTarget().getType().equals(type)) {
+        result.add(target.containingEndpointDefinition());
       }
     }
     return result;
@@ -37,17 +39,22 @@ aspect Analysis {
   }
 
   // --- isAlreadyDefined ---
-  syn boolean TokenEndpointDefinition.isAlreadyDefined() {
+  syn boolean EndpointDefinition.isAlreadyDefined() = getEndpointTarget().isAlreadyDefined();
+  syn boolean EndpointTarget.isAlreadyDefined();
+  eq TokenEndpointTarget.isAlreadyDefined() {
     return lookupTokenEndpointDefinitions(getToken()).stream()
-      .filter(this::matchesType)
+      .filter(containingEndpointDefinition()::matchesType)
+      .count() > 1;
+  }
+  eq TypeEndpointTarget.isAlreadyDefined() {
+    return lookupTypeEndpointDefinitions(getType()).stream()
+      .filter(containingEndpointDefinition()::matchesType)
       .count() > 1;
   }
   syn boolean DependencyDefinition.isAlreadyDefined() = lookupDependencyDefinition(getSource().containingTypeDecl(), getID()) != this;
 
   // --- matchesType ---
-  syn boolean TokenEndpointDefinition.matchesType(TokenEndpointDefinition other);
-  eq ReceiveTokenEndpointDefinition.matchesType(TokenEndpointDefinition other) = other.isReceiveTokenEndpointDefinition();
-  eq SendTokenEndpointDefinition.matchesType(TokenEndpointDefinition other) = other.isSendTokenEndpointDefinition();
+  syn boolean EndpointDefinition.matchesType(EndpointDefinition other) = this.getSend() == other.getSend();
 
   // --- assignableTo ---
   syn boolean MappingDefinitionType.assignableTo(JavaTypeUse target);
@@ -81,11 +88,14 @@ aspect Analysis {
   }
 
   // --- shouldSendValue ---
-  syn boolean TokenEndpointDefinition.shouldSendValue() = isSendTokenEndpointDefinition() && !getToken().getNTA();
-  syn boolean TypeEndpointDefinition.shouldSendValue() = isSendTypeEndpointDefinition() && !getType().getNTA();
+  syn boolean EndpointDefinition.shouldSendValue() = getSend() && getEndpointTarget().entityIsNormalAttribute();
+
+  syn boolean EndpointTarget.entityIsNormalAttribute();
+  eq TokenEndpointTarget.entityIsNormalAttribute() = !getToken().getNTA();
+  eq TypeEndpointTarget.entityIsNormalAttribute() = !getType().getNTA();
 
   // --- needProxyToken ---
-  syn boolean TokenComponent.needProxyToken() = !getDependencySourceDefinitionList().isEmpty() || getTokenEndpointDefinitionList().stream().anyMatch(TokenEndpointDefinition::shouldSendValue);
+  syn boolean TokenComponent.needProxyToken() = !getDependencySourceDefinitionList().isEmpty() || getTokenEndpointTargetList().stream().map(EndpointTarget::containingEndpointDefinition).anyMatch(EndpointDefinition::shouldSendValue);
 
   // --- effectiveUsedAt ---
   coll Set<EndpointDefinition> MappingDefinition.effectiveUsedAt()
@@ -96,8 +106,9 @@ aspect Analysis {
     for each effectiveMappings();
 
   // --- typeIsList ---
-  syn boolean EndpointDefinition.typeIsList() = false;
-  eq TypeEndpointDefinition.typeIsList() {
+  syn boolean EndpointDefinition.typeIsList() = getEndpointTarget().typeIsList();
+  syn boolean EndpointTarget.typeIsList() = false;
+  eq TypeEndpointTarget.typeIsList() {
     return getType().isListComponent();
   }
 
diff --git a/ragconnect.base/src/main/jastadd/Errors.jrag b/ragconnect.base/src/main/jastadd/Errors.jrag
index 770e506cc5c0145a0ba9979d57a1086a399ed39e..610f99474484143ad1e4cc39a6b4bc814759c06b 100644
--- a/ragconnect.base/src/main/jastadd/Errors.jrag
+++ b/ragconnect.base/src/main/jastadd/Errors.jrag
@@ -3,29 +3,27 @@ aspect Errors {
     [new TreeSet<ErrorMessage>()]
     root RagConnect;
 
-    ReceiveTokenEndpointDefinition contributes error("Receive definition already defined for " + getToken().getName())
+    EndpointDefinition contributes error("Endpoint definition already defined for " + parentTypeName() + "." + entityName())
       when isAlreadyDefined()
       to RagConnect.errors();
 
-    ReceiveTokenEndpointDefinition contributes error("Receiving target token must not be an NTA token!")
-      when getToken().getNTA()
+    EndpointDefinition contributes error("Receiving target token must not be an NTA token!")
+      when !getSend() && getEndpointTarget().isTokenEndpointTarget() && token().getNTA()
       to RagConnect.errors();
 
     // if first mapping is null, then suitableDefaultMapping() == null
-    ReceiveTokenEndpointDefinition contributes error("No suitable default mapping found for type " +
+    EndpointDefinition contributes error("No suitable default mapping found for type " +
       ((getMappingList().isEmpty())
-        ? getToken().effectiveJavaTypeUse().prettyPrint()
+        ? token().effectiveJavaTypeUse().prettyPrint()
         : getMappingList().get(0).getFromType().prettyPrint()))
-      when effectiveMappings().get(0) == null
+      when !getSend() && getEndpointTarget().isTokenEndpointTarget() && effectiveMappings().get(0) == null
       to RagConnect.errors();
 
-    ReceiveTokenEndpointDefinition contributes error("to-type of last mapping (" + effectiveMappings().get(effectiveMappings().size() - 1).getToType().prettyPrint() + ") not assignable to type of the Token (" + getToken().effectiveJavaTypeUse().prettyPrint() + ")!")
-      when !effectiveMappings().get(effectiveMappings().size() - 1).getToType().assignableTo(
-          getToken().effectiveJavaTypeUse())
-      to RagConnect.errors();
-
-    SendTokenEndpointDefinition contributes error("Send definition already defined for " + getToken().getName())
-      when isAlreadyDefined()
+    // TODO copy for type endpoint target
+    EndpointDefinition contributes error("to-type of last mapping (" + effectiveMappings().get(effectiveMappings().size() - 1).getToType().prettyPrint() + ") not assignable to type of the token (" + token().effectiveJavaTypeUse().prettyPrint() + ")!")
+      when !getSend() && getEndpointTarget().isTokenEndpointTarget() &&
+           !effectiveMappings().get(effectiveMappings().size() - 1).getToType().assignableTo(
+            token().effectiveJavaTypeUse())
       to RagConnect.errors();
 
     DependencyDefinition contributes error("Dependency definition already defined for " + getSource().containingTypeDecl().getName() + " with name " + getID())
@@ -46,7 +44,6 @@ aspect ErrorHelpers {
     }
     return false;
   }
-  syn String TokenComponent.parentTypeDeclAndName() = containingTypeDecl().getName() + "." + getName();
 }
 
 aspect ErrorMessage {
diff --git a/ragconnect.base/src/main/jastadd/Navigation.jrag b/ragconnect.base/src/main/jastadd/Navigation.jrag
index a4de1f555d63e27d587571d3ac2de9d82263a3ac..615c671928b42eaaa074c2514bf158a8390d3509 100644
--- a/ragconnect.base/src/main/jastadd/Navigation.jrag
+++ b/ragconnect.base/src/main/jastadd/Navigation.jrag
@@ -43,24 +43,24 @@ aspect RagConnectNavigation {
 
   // --- program ---
   eq RagConnect.getChild().program() = getProgram();
-  eq MRagConnect.getChild().program() = getRagConnect().program();
 
   // --- ragconnect ---
   inh RagConnect ASTNode.ragconnect();
   eq RagConnect.getChild().ragconnect() = this;
-  eq MRagConnect.getChild().ragconnect() = getRagConnect();
 
   // --- containedConnectSpecification ---
   inh ConnectSpecification ASTNode.containedConnectSpecification();
   eq RagConnect.getChild().containedConnectSpecification() = null;
-  eq MRagConnect.getChild().containedConnectSpecification() = null;
   eq Document.getChild().containedConnectSpecification() = null;
   eq Program.getChild().containedConnectSpecification() = null;
   eq ConnectSpecification.getChild().containedConnectSpecification() = this;
 
+  // --- containingEndpointDefinition ---
+  inh EndpointDefinition EndpointTarget.containingEndpointDefinition();
+  eq EndpointDefinition.getEndpointTarget().containingEndpointDefinition() = this;
+
   // --- containedFile
   eq RagConnect.getChild().containedFile() = null;
-  eq MRagConnect.getChild().containedFile() = null;
 
   // --- containedFileName ---
   eq ConnectSpecificationFile.containedFileName() = getFileName();
@@ -75,16 +75,25 @@ aspect RagConnectNavigation {
   //--- allEndpointDefinitionList ---
   syn List<EndpointDefinition> RagConnect.allEndpointDefinitionList() {
     List<EndpointDefinition> result = new ArrayList<>();
-    for (var spec : getConnectSpecificationFileList()) {
+    for (ConnectSpecification spec : getConnectSpecificationFileList()) {
       spec.getEndpointDefinitionList().forEach(result::add);
     }
     return result;
   }
 
+  //--- allEndpointTargetList ---
+  syn List<EndpointTarget> RagConnect.allEndpointTargetList() {
+    List<EndpointTarget> result = new ArrayList<>();
+    for (ConnectSpecification spec : getConnectSpecificationFileList()) {
+      spec.getEndpointDefinitionList().forEach(endpointDef -> result.add(endpointDef.getEndpointTarget()));
+    }
+    return result;
+  }
+
   //--- allDependencyDefinitionList ---
   syn List<DependencyDefinition> RagConnect.allDependencyDefinitionList() {
     List<DependencyDefinition> result = new ArrayList<>();
-    for (var spec : getConnectSpecificationFileList()) {
+    for (ConnectSpecification spec : getConnectSpecificationFileList()) {
       spec.getDependencyDefinitionList().forEach(result::add);
     }
     return result;
@@ -93,70 +102,24 @@ aspect RagConnectNavigation {
   //--- allMappingDefinitionList ---
   syn List<MappingDefinition> RagConnect.allMappingDefinitionList() {
     List<MappingDefinition> result = new ArrayList<>();
-    for (var spec : getConnectSpecificationFileList()) {
+    for (ConnectSpecification spec : getConnectSpecificationFileList()) {
       spec.getMappingDefinitionList().forEach(result::add);
     }
     return result;
   }
 
-  // --- isTokenEndpointDefinition ---
-  syn boolean EndpointDefinition.isTokenEndpointDefinition() = false;
-  eq TokenEndpointDefinition.isTokenEndpointDefinition() = true;
-
-  // --- asTokenEndpointDefinition ---
-  syn TokenEndpointDefinition EndpointDefinition.asTokenEndpointDefinition() = null;
-  eq TokenEndpointDefinition.asTokenEndpointDefinition() = this;
-
-  // --- isTypeEndpointDefinition ---
-  syn boolean EndpointDefinition.isTypeEndpointDefinition() = false;
-  eq TypeEndpointDefinition.isTypeEndpointDefinition() = true;
-
-  // --- asTypeEndpointDefinition ---
-  syn TypeEndpointDefinition EndpointDefinition.asTypeEndpointDefinition() = null;
-  eq TypeEndpointDefinition.asTypeEndpointDefinition() = this;
-
-  // --- isReceiveTokenEndpointDefinition ---
-  syn boolean EndpointDefinition.isReceiveTokenEndpointDefinition() = false;
-  eq ReceiveTokenEndpointDefinition.isReceiveTokenEndpointDefinition() = true;
-
-  // --- asReceiveTokenEndpointDefinition ---
-  syn ReceiveTokenEndpointDefinition EndpointDefinition.asReceiveTokenEndpointDefinition() = null;
-  eq ReceiveTokenEndpointDefinition.asReceiveTokenEndpointDefinition() = this;
-
-  // --- isSendTokenEndpointDefinition ---
-  syn boolean EndpointDefinition.isSendTokenEndpointDefinition() = false;
-  eq SendTokenEndpointDefinition.isSendTokenEndpointDefinition() = true;
-
-  // --- asSendTokenEndpointDefinition ---
-  syn SendTokenEndpointDefinition EndpointDefinition.asSendTokenEndpointDefinition() = null;
-  eq SendTokenEndpointDefinition.asSendTokenEndpointDefinition() = this;
-
-  // --- isReceiveTypeEndpointDefinition ---
-  syn boolean EndpointDefinition.isReceiveTypeEndpointDefinition() = false;
-  eq ReceiveTypeEndpointDefinition.isReceiveTypeEndpointDefinition() = true;
-
-  // --- asReceiveTypeEndpointDefinition ---
-  syn ReceiveTypeEndpointDefinition EndpointDefinition.asReceiveTypeEndpointDefinition() = null;
-  eq ReceiveTypeEndpointDefinition.asReceiveTypeEndpointDefinition() = this;
-
-  // --- isSendTypeEndpointDefinition ---
-  syn boolean EndpointDefinition.isSendTypeEndpointDefinition() = false;
-  eq SendTypeEndpointDefinition.isSendTypeEndpointDefinition() = true;
-
-  // --- asSendTypeEndpointDefinition ---
-  syn SendTypeEndpointDefinition EndpointDefinition.asSendTypeEndpointDefinition() = null;
-  eq SendTypeEndpointDefinition.asSendTypeEndpointDefinition() = this;
-
   // --- targetEndpointDefinition ---
   syn EndpointDefinition DependencyDefinition.targetEndpointDefinition() {
     // resolve definition in here, as we do not need resolveMethod in any other place (yet)
     for (EndpointDefinition endpointDefinition : ragconnect().allEndpointDefinitionList()) {
-      if (endpointDefinition.isSendTokenEndpointDefinition() &&
-          endpointDefinition.asSendTokenEndpointDefinition().getToken().equals(this.getTarget())) {
+      if (!endpointDefinition.getSend()) { continue; }
+      EndpointTarget endpointTarget = endpointDefinition.getEndpointTarget();
+      if (endpointTarget.isTokenEndpointTarget() &&
+          endpointTarget.asTokenEndpointTarget().getToken().equals(this.getTarget())) {
         return endpointDefinition;
       }
-      if (endpointDefinition.isSendTypeEndpointDefinition() &&
-          endpointDefinition.asSendTypeEndpointDefinition().getType().equals(this.getTarget())) {
+      if (endpointTarget.isTypeEndpointTarget() &&
+          endpointTarget.asTypeEndpointTarget().getType().equals(this.getTarget())) {
         return endpointDefinition;
       }
     }
@@ -170,13 +133,6 @@ aspect RagConnectNavigation {
   syn boolean MappingDefinition.isDefaultMappingDefinition() = false;
   eq DefaultMappingDefinition.isDefaultMappingDefinition() = true;
 
-  // --- mragconnect ---
-  inh MRagConnect MHandler.mragconnect();
-  eq MRagConnect.getHandler().mragconnect() = this;
-
-  // --- rootTypeComponents ---
-  syn JastAddList<MTypeComponent> MHandler.rootTypeComponents() = mragconnect().getRootTypeComponents();
-
   // --- isListComponent --- (defined in PP, but only on TypeComponent)
   syn boolean Component.isListComponent() = false;
 }
diff --git a/ragconnect.base/src/main/jastadd/RagConnect.relast b/ragconnect.base/src/main/jastadd/RagConnect.relast
index 4301c70e77435e46fb131b093e9009577109d680..c0037c765971157a21e1e5029f9e52de29bdece9 100644
--- a/ragconnect.base/src/main/jastadd/RagConnect.relast
+++ b/ragconnect.base/src/main/jastadd/RagConnect.relast
@@ -1,23 +1,21 @@
-RagConnect ::= ConnectSpecificationFile* Program ;
+RagConnect ::= ConnectSpecificationFile* Handler* Program ;
 
 abstract ConnectSpecification ::= EndpointDefinition* DependencyDefinition* MappingDefinition* ;
 ConnectSpecificationFile : ConnectSpecification ::= <FileName> ;
 
-abstract EndpointDefinition ::= <AlwaysApply:boolean> ;
-
+EndpointDefinition ::= <AlwaysApply:boolean> <IndexBasedListAccess:boolean> <WithAdd:boolean> <Send:boolean> EndpointTarget ;
 rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*;
 
-abstract TokenEndpointDefinition : EndpointDefinition;
-rel TokenEndpointDefinition.Token <-> TokenComponent.TokenEndpointDefinition*;
-
-ReceiveTokenEndpointDefinition : TokenEndpointDefinition;
-SendTokenEndpointDefinition : TokenEndpointDefinition;
-
-abstract TypeEndpointDefinition : EndpointDefinition ::= <IndexBasedListAccess:boolean> ;
-rel TypeEndpointDefinition.Type <-> TypeComponent.TypeEndpointDefinition*;
-
-ReceiveTypeEndpointDefinition : TypeEndpointDefinition ::= <WithAdd:boolean>;
-SendTypeEndpointDefinition : TypeEndpointDefinition;
+abstract EndpointTarget ;
+TokenEndpointTarget : EndpointTarget ;
+rel TokenEndpointTarget.Token <-> TokenComponent.TokenEndpointTarget* ;
+TypeEndpointTarget : EndpointTarget ;
+rel TypeEndpointTarget.Type <-> TypeComponent.TypeEndpointTarget* ;
+UntypedEndpointTarget : EndpointTarget ::= <TokenOrType> ;  // only used by parser
+// to be integrated:
+//AttributeEndpointTarget : EndpointTarget ::= <Name> ;
+//RelationEndpointTarget : EndpointTarget ;
+//rel RelationEndpointTarget.Role <-> Role.RelationEndpointTarget* ;
 
 DependencyDefinition ::= <ID>;
 rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
@@ -29,7 +27,4 @@ JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
 JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
 DefaultMappingDefinition : MappingDefinition ;
 
-// only used by parser
-abstract UntypedEndpointDefinition : EndpointDefinition ::= <TokenOrType> <Indexed:boolean> <WithAdd:boolean> ;
-ReceiveUntypedEndpointDefinition : UntypedEndpointDefinition;
-SendUntypedEndpointDefinition : UntypedEndpointDefinition;
+Handler ::= <ClassName> <Construction> <AttributeName> <FieldName> <InUse:boolean>;
diff --git a/ragconnect.base/src/main/jastadd/RagConnect_concise.relast b/ragconnect.base/src/main/jastadd/RagConnect_concise.relast
deleted file mode 100644
index 2c8a723774e76e124feaebbd2835e12aee6e5e6b..0000000000000000000000000000000000000000
--- a/ragconnect.base/src/main/jastadd/RagConnect_concise.relast
+++ /dev/null
@@ -1,28 +0,0 @@
-RagConnect ::= ConnectSpecificationFile* Program ;
-
-abstract ConnectSpecification ::= EndpointDefinition* DependencyDefinition* MappingDefinition* ;
-ConnectSpecificationFile : ConnectSpecification ::= <FileName> ;
-
-EndpointDefinition ::= <AlwaysApply:boolean> <IndexBasedListAccess:boolean> <WithAdd:boolean> <Send:boolean> EndpointTarget ;
-rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*;
-
-abstract EndpointTarget ;
-TokenEndpointTarget : EndpointTarget ;
-rel TokenEndpointTarget.Token <-> TokenComponent.TokenEndpointTarget* ;
-TypeEndpointTarget : EndpointTarget ;
-rel TypeEndpointTarget.Type <-> TypeComponent.TypeEndpointTarget* ;
-UntypedEndpointTarget : EndpointTarget ::= <TokenOrType> ;  // only used by parser
-// to be integrated:
-//AttributeEndpointTarget : EndpointTarget ::= <Name> ;
-//RelationEndpointTarget : EndpointTarget ;
-//rel RelationEndpointTarget.Role <-> Role.RelationEndpointTarget* ;
-
-DependencyDefinition ::= <ID>;
-rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
-rel DependencyDefinition.Target -> Component;
-
-MappingDefinition ::= <ID> FromType:MappingDefinitionType <FromVariableName> ToType:MappingDefinitionType <Content> ;
-abstract MappingDefinitionType ::= ;
-JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
-JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
-DefaultMappingDefinition : MappingDefinition ;
diff --git a/ragconnect.base/src/main/jastadd/RagConnect_old.relast b/ragconnect.base/src/main/jastadd/RagConnect_old.relast
new file mode 100644
index 0000000000000000000000000000000000000000..4301c70e77435e46fb131b093e9009577109d680
--- /dev/null
+++ b/ragconnect.base/src/main/jastadd/RagConnect_old.relast
@@ -0,0 +1,35 @@
+RagConnect ::= ConnectSpecificationFile* Program ;
+
+abstract ConnectSpecification ::= EndpointDefinition* DependencyDefinition* MappingDefinition* ;
+ConnectSpecificationFile : ConnectSpecification ::= <FileName> ;
+
+abstract EndpointDefinition ::= <AlwaysApply:boolean> ;
+
+rel EndpointDefinition.Mapping* <-> MappingDefinition.UsedAt*;
+
+abstract TokenEndpointDefinition : EndpointDefinition;
+rel TokenEndpointDefinition.Token <-> TokenComponent.TokenEndpointDefinition*;
+
+ReceiveTokenEndpointDefinition : TokenEndpointDefinition;
+SendTokenEndpointDefinition : TokenEndpointDefinition;
+
+abstract TypeEndpointDefinition : EndpointDefinition ::= <IndexBasedListAccess:boolean> ;
+rel TypeEndpointDefinition.Type <-> TypeComponent.TypeEndpointDefinition*;
+
+ReceiveTypeEndpointDefinition : TypeEndpointDefinition ::= <WithAdd:boolean>;
+SendTypeEndpointDefinition : TypeEndpointDefinition;
+
+DependencyDefinition ::= <ID>;
+rel DependencyDefinition.Source <-> TokenComponent.DependencySourceDefinition*;
+rel DependencyDefinition.Target -> Component;
+
+MappingDefinition ::= <ID> FromType:MappingDefinitionType <FromVariableName> ToType:MappingDefinitionType <Content> ;
+abstract MappingDefinitionType ::= ;
+JavaMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
+JavaArrayMappingDefinitionType : MappingDefinitionType ::= Type:JavaTypeUse ;
+DefaultMappingDefinition : MappingDefinition ;
+
+// only used by parser
+abstract UntypedEndpointDefinition : EndpointDefinition ::= <TokenOrType> <Indexed:boolean> <WithAdd:boolean> ;
+ReceiveUntypedEndpointDefinition : UntypedEndpointDefinition;
+SendUntypedEndpointDefinition : UntypedEndpointDefinition;
diff --git a/ragconnect.base/src/main/jastadd/intermediate/Generation.jadd b/ragconnect.base/src/main/jastadd/intermediate/Generation.jadd
index 755830fa705a8ff80870ef529c605e75fe29bc95..83a89d6d2ca9d24d77457ec400a27e3f73f22890 100644
--- a/ragconnect.base/src/main/jastadd/intermediate/Generation.jadd
+++ b/ragconnect.base/src/main/jastadd/intermediate/Generation.jadd
@@ -4,18 +4,18 @@ Design considerations
 - [NEW in 1.0.0] no complete intermediate structure, but instead single nodes where applicable
 */
 aspect NewStuff {
-  syn nta JastAddList<MTypeComponent> RagConnect.getRootTypeComponentList() {
-    JastAddList<MTypeComponent> result = new JastAddList<>();
+  syn List<TypeComponent> RagConnect.rootTypeComponentList() {
+    List<TypeComponent> result = new ArrayList<>();
     for (Component child : rootNode.getComponentList()) {
       if (child.isTypeComponent()) {
-        result.add(child.asTypeComponent().toMustache());
+        result.add(child.asTypeComponent());
       }
     }
     return result;
   }
 
-  inh boolean MTypeComponent.isFirst();
-  eq RagConnect.getRootTypeComponentList(int i).isFirst() = i == 0;
+//  inh boolean TypeComponent.isFirst();
+//  eq RagConnect.getRootTypeComponentList(int i).isFirst() = i == 0;
 
   syn String RagConnect.closeMethod() = "ragconnectCloseConnections";
   syn String RagConnect.mqttHandlerAttribute() = "_mqttHandler";
@@ -26,7 +26,7 @@ aspect NewStuff {
   syn String RagConnect.restHandlerField() = "_restHandler";
 
   syn boolean RagConnect.hasTreeListEndpoints() {
-    for (EndpointDefinition endpointDef : getEndpointDefinitionList()) {
+    for (EndpointDefinition endpointDef : allEndpointDefinitionList()) {
       if (endpointDef.typeIsList()) {
         return true;
       }
@@ -35,7 +35,7 @@ aspect NewStuff {
   }
   syn Set<TypeDecl> RagConnect.typesForReceivingListEndpoints() {
     Set<TypeDecl> result = new HashSet<>();
-    for (EndpointDefinition endpointDef : getEndpointDefinitionList()) {
+    for (EndpointDefinition endpointDef : allEndpointDefinitionList()) {
       if (endpointDef.typeIsList() && !endpointDef.getSend()) {
         result.add(endpointDef.type().getTypeDecl());
       }
@@ -46,290 +46,219 @@ aspect NewStuff {
   syn String EndpointDefinition.preemptiveExpectedValue() = toMustache().preemptiveExpectedValue();
   syn String EndpointDefinition.preemptiveReturn() = toMustache().preemptiveReturn();
   syn String EndpointDefinition.firstInputVarName() = toMustache().firstInputVarName();
-  syn String EndpointDefinition.parentTypeName() = toMustache().parentTypeName();
-  syn String EndpointDefinition.entityName() = toMustache().entityName();
   syn String EndpointDefinition.updateMethod() = toMustache().updateMethod();
   syn String EndpointDefinition.writeMethod() = toMustache().writeMethod();
-  syn String EndpointDefinition.getterMethod() = toMustache().getterMethod();
+
+  syn String EndpointDefinition.parentTypeName() = getEndpointTarget().parentTypeName();
+  syn String EndpointDefinition.entityName() = getEndpointTarget().entityName();
+  syn String EndpointDefinition.getterMethod() = getEndpointTarget().getterMethod();
 
   syn String EndpointDefinition.uniqueSuffix() = getSend() ? "Send" : "Receive";
 
   syn String EndpointDefinition.connectParameterName() = "uriString";
   syn String EndpointDefinition.connectMethod() = "connect" + entityName();
   syn String EndpointDefinition.internalConnectMethod() = "_internal_" + connectMethod();
-  syn boolean EndpointDefinition.isTypeEndpointDefinition() = endpointDef().isTypeEndpointDefinition();
 
   syn String EndpointDefinition.disconnectMethod() {
-    // TODO unclear. rework, when lookup methods are done.
     // if both (send and receive) are defined for an endpoint, ensure methods with different names
     String extra;
-    if (endpointDef().isTokenEndpointDefinition()) {
-      extra = endpointDef().asTokenEndpointDefinition().lookupTokenEndpointDefinitions(token()).size() > 1 ? uniqueSuffix() : "";
-    } else if (endpointDef().isTypeEndpointDefinition()) {
-      extra = endpointDef().asTypeEndpointDefinition().lookupTypeEndpointDefinitions(type()).size() > 1 ? uniqueSuffix() : "";
+    if (getEndpointTarget().isTokenEndpointTarget()) {
+      extra = lookupTokenEndpointDefinitions(token()).size() > 1 ? uniqueSuffix() : "";
+    } else if (getEndpointTarget().isTypeEndpointTarget()) {
+      extra = lookupTypeEndpointDefinitions(type()).size() > 1 ? uniqueSuffix() : "";
     } else {
       extra = "";
     }
     return "disconnect" + extra + entityName();
   }
-  // TODO potentially dangerous because asXEndpointDefinition can return null
+  // TODO [OLD] potentially dangerous because asXEndpointDefinition can return null
   syn TokenComponent EndpointDefinition.token() = getEndpointTarget().asTokenEndpointTarget().getToken();
   syn TypeComponent EndpointDefinition.type() = getEndpointTarget().asTypeEndpointTarget().getType();
   syn String EndpointDefinition.tokenName() = token().getName();
+  syn String MEndpointDefinition.tokenName() = getEndpointDefinition().tokenName();
   syn String EndpointDefinition.typeName() = type().getName();
+  syn String MEndpointDefinition.typeName() = getEndpointDefinition().typeName();
   syn String EndpointDefinition.typeDeclName() = type().getTypeDecl().getName();
-}
-
-aspect OldStuff {
-  // --- EndpointDefinition ---
-  syn String EndpointDefinition.idTokenName() = "InternalRagconnectTopicInList";
-
-  // --- MEndpointDefinition ---
-  syn String MEndpointDefinition.preemptiveExpectedValue();
-  syn String MEndpointDefinition.preemptiveReturn();
-  syn EndpointDefinition MEndpointDefinition.endpointDef();
-  syn String MEndpointDefinition.firstInputVarName();
-  syn String MEndpointDefinition.parentTypeName();
-  syn String MEndpointDefinition.entityName();
-  syn String MEndpointDefinition.updateMethod();
-  syn String MEndpointDefinition.writeMethod();
-  syn String MEndpointDefinition.getterMethod();
 
+  syn MInnerMappingDefinition EndpointDefinition.lastDefinition() = toMustache().lastDefinition();
+  syn MInnerMappingDefinition MEndpointDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
+  syn String EndpointDefinition.lastDefinitionToType() = lastDefinition().toType();
+  syn String EndpointDefinition.lastResult() = lastDefinition().outputVarName();
+  // TODO check, whether this works
+  inh boolean MInnerMappingDefinition.isLast();
   eq MEndpointDefinition.getInnerMappingDefinition(int i).isLast() = i == getNumInnerMappingDefinition() - 1;
   eq MEndpointDefinition.getInnerMappingDefinition(int i).inputVarName() = i == 0 ? firstInputVarName() : getInnerMappingDefinition(i - 1).outputVarName();
 
-}
-
-aspect AttributesForMustache {
-  syn MInnerMappingDefinition MEndpointDefinition.lastDefinition() = getInnerMappingDefinition(getNumInnerMappingDefinition() - 1);
-  syn String MEndpointDefinition.lastDefinitionToType() = lastDefinition().toType();
-  syn String MEndpointDefinition.lastResult() = lastDefinition().outputVarName();
-  syn String MEndpointDefinition.condition() {
-    // TODO probably, this has to be structured in a better way
-    if (lastDefinition().mappingDef().getToType().isArray()) {
+  syn String EndpointDefinition.condition() {
+    // TODO [OLD] probably, this has to be structured in a better way
+    if (lastDefinition().getMappingDefinition().getToType().isArray()) {
       return "java.util.Arrays.equals(" + preemptiveExpectedValue() + ", " + lastResult() + ")";
     }
-    if (endpointDef().isTokenEndpointDefinition() && token().isPrimitiveType() && lastDefinition().mappingDef().getToType().isPrimitiveType()) {
+    if (getEndpointTarget().isTokenEndpointTarget() && token().isPrimitiveType() && lastDefinition().getMappingDefinition().getToType().isPrimitiveType()) {
       return preemptiveExpectedValue() + " == " + lastResult();
     }
-    if (endpointDef().isReceiveTypeEndpointDefinition() && endpointDef().asReceiveTypeEndpointDefinition().getWithAdd()) {
+    if (!getSend() && getEndpointTarget().isTypeEndpointTarget() && getWithAdd()) {
       // only check if received list is not null
       return lastResult() + " == null";
     }
-    if (endpointDef().isTypeEndpointDefinition() && type().isOptComponent()) {
+    if (getEndpointTarget().isTypeEndpointTarget() && type().isOptComponent()) {
       // use "hasX()" instead of "getX() != null" for optionals
       return "has" + typeName() + "()" + " && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
     }
-    if (lastDefinition().mappingDef().getToType().isPrimitiveType() || lastDefinition().mappingDef().isDefaultMappingDefinition()) {
+    if (lastDefinition().getMappingDefinition().getToType().isPrimitiveType() || lastDefinition().getMappingDefinition().isDefaultMappingDefinition()) {
       return preemptiveExpectedValue() + " != null && " + preemptiveExpectedValue() + ".equals(" + lastResult() + ")";
     }
     return preemptiveExpectedValue() + " != null ? " + preemptiveExpectedValue() + ".equals(" + lastResult() + ") : " + lastResult() + " == null";
   }
-  syn String MEndpointDefinition.sender() = null; // only for M*SendDefinitions
-  syn String MEndpointDefinition.lastValue() = sender() + ".lastValue"; // only for M*SendDefinitions
-
-  // --- MTokenEndpointDefinition ---
-  eq MTokenEndpointDefinition.getterMethod() = "get" + tokenName();
-  eq MTokenEndpointDefinition.parentTypeName() = token().containingTypeDecl().getName();
-  eq MTokenEndpointDefinition.entityName() = tokenName();
-
-  // --- MTypeEndpointDefinition ---
-  syn boolean MTypeEndpointDefinition.isWithAdd() = endpointDef().isReceiveTypeEndpointDefinition() ? endpointDef().asReceiveTypeEndpointDefinition().getWithAdd() : false;
-  syn boolean MTypeEndpointDefinition.isIndexBasedListAccess() = endpointDef().asTypeEndpointDefinition().getIndexBasedListAccess();
-  eq MTypeEndpointDefinition.getterMethod() = "get" + typeName() + (typeIsList() ? "List" : "");
-  eq MTypeEndpointDefinition.parentTypeName() = type().containingTypeDecl().getName();
-  eq MTypeEndpointDefinition.entityName() = typeName() + (typeIsList() && !isIndexBasedListAccess() ? "List" : "");
-
-  // --- MInnerMappingDefinition ---
-  inh boolean MInnerMappingDefinition.isLast();
-  inh String MInnerMappingDefinition.inputVarName();
-  syn String MInnerMappingDefinition.toType() = mappingDef().getToType().prettyPrint();
-  syn String MInnerMappingDefinition.methodName() = getMMappingDefinition().methodName();
-  syn MappingDefinition MInnerMappingDefinition.mappingDef() = getMMappingDefinition().getMappingDefinition();
-  syn String MInnerMappingDefinition.outputVarName() = "result" + methodName();  // we do not need "_" in between here, because methodName begins with one
-
-  // --- MTokenReceiveDefinition ---
-  eq MTokenReceiveDefinition.preemptiveExpectedValue() = getterMethod() + "()";
-  eq MTokenReceiveDefinition.preemptiveReturn() = "return;";
-  eq MTokenReceiveDefinition.endpointDef() = getReceiveTokenEndpointDefinition();
-  eq MTokenReceiveDefinition.firstInputVarName() = "message";
-  eq MTokenReceiveDefinition.updateMethod() = null;
-  eq MTokenReceiveDefinition.writeMethod() = null;
-
-  // --- MTokenSendDefinition ---
-  eq MTokenSendDefinition.preemptiveExpectedValue() = lastValue();
-  eq MTokenSendDefinition.preemptiveReturn() = "return false;";
-  eq MTokenSendDefinition.endpointDef() = getSendTokenEndpointDefinition();
-  eq MTokenSendDefinition.firstInputVarName() = getterMethod() + "()";
-  eq MTokenSendDefinition.updateMethod() = "_update_" + tokenName();
-  eq MTokenSendDefinition.writeMethod() = "_writeLastValue_" + tokenName();
-
-  eq MTokenSendDefinition.sender() = "_sender_" + tokenName();
-  syn String MTokenSendDefinition.tokenResetMethod() = getterMethod() + "_reset";
-  syn boolean MTokenSendDefinition.shouldSendValue() = endpointDef().asTokenEndpointDefinition().shouldSendValue();
-
-  // MTypeReceiveDefinition
-  eq MTypeReceiveDefinition.preemptiveExpectedValue() = getterMethod() + "()";
-  eq MTypeReceiveDefinition.preemptiveReturn() = "return;";
-  eq MTypeReceiveDefinition.endpointDef() = getReceiveTypeEndpointDefinition();
-  eq MTypeReceiveDefinition.firstInputVarName() = "message";
-  eq MTypeReceiveDefinition.updateMethod() = null;
-  eq MTypeReceiveDefinition.writeMethod() = null;
-
-  syn String MTypeReceiveDefinition.resolveInListMethodName() = "_ragconnect_resolve" + entityName() + "InList";
-  syn String MTypeReceiveDefinition.idTokenName() = endpointDef().idTokenName();
-
-  // MTypeSendDefinition
-  eq MTypeSendDefinition.preemptiveExpectedValue() = lastValue();
-  eq MTypeSendDefinition.preemptiveReturn() = "return false;";
-  eq MTypeSendDefinition.endpointDef() = getSendTypeEndpointDefinition();
-  eq MTypeSendDefinition.firstInputVarName() = getterMethod() + "()";
-  eq MTypeSendDefinition.updateMethod() = "_update_" + typeName();
-  eq MTypeSendDefinition.writeMethod() = "_writeLastValue_" + typeName();
 
-  eq MTypeSendDefinition.sender() = "_sender_" + typeName();
-  syn String MTypeSendDefinition.tokenResetMethod() = getterMethod() + "_reset";
-  syn boolean MTypeSendDefinition.shouldSendValue() = endpointDef().asTypeEndpointDefinition().shouldSendValue();
+  // TODO rename sender to senderName
+  syn String EndpointDefinition.sender() = getEndpointTarget().senderName(); // only needed for send endpoints
+  syn String EndpointTarget.senderName();
+  eq TokenEndpointTarget.senderName() = "_sender_" + getToken().getName();
+  eq TypeEndpointTarget.senderName() = "_sender_" + getType().getName();
+  syn String EndpointDefinition.lastValue() = sender() + ".lastValue"; // only needed for send endpoints
+  syn String MEndpointDefinition.lastValue() = getEndpointDefinition().lastValue();
+
+  // TODO rename getterMethod to getterMethodName
+  syn String EndpointTarget.getterMethod();
+  syn String EndpointTarget.parentTypeName();
+  syn String EndpointTarget.entityName();
+  eq TokenEndpointTarget.getterMethod() = "get" + getToken().getName();
+  eq TokenEndpointTarget.parentTypeName() = getToken().containingTypeDecl().getName();
+  eq TokenEndpointTarget.entityName() = getToken().getName();
+  eq TypeEndpointTarget.getterMethod() = "get" + getType().getName() + (typeIsList() ? "List" : "");
+  eq TypeEndpointTarget.parentTypeName() = getType().containingTypeDecl().getName();
+  eq TypeEndpointTarget.entityName() = getType().getName() + (typeIsList() && !containingEndpointDefinition().getIndexBasedListAccess() ? "List" : "");
+
+  // only for token + send
+  // TODO rename tokenResetMethod to tokenResetMethodName
+  syn String EndpointDefinition.tokenResetMethod() = getterMethod() + "_reset";
+
+  // only for type + receive
+  syn String EndpointDefinition.resolveInListMethodName() = "_ragconnect_resolve" + entityName() + "InList";
 
   // --- MMappingDefinition ---
-  syn String MMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
-  syn String MMappingDefinition.methodName() = "_apply_" + getMappingDefinition().getID();
-  syn String MMappingDefinition.fromType() = getMappingDefinition().getFromType().prettyPrint();
-  syn String MMappingDefinition.fromVariableName() = getMappingDefinition().getFromVariableName();
-  syn String MMappingDefinition.content() = getMappingDefinition().getContent();
-  syn boolean MMappingDefinition.isUsed() = !getMappingDefinition().effectiveUsedAt().isEmpty();
+  syn String MappingDefinition.toType() = getToType().prettyPrint();
+  syn String MappingDefinition.methodName() = "_apply_" + getID();
+  syn String MappingDefinition.fromType() = getFromType().prettyPrint();
+  syn boolean MappingDefinition.isUsed() = !effectiveUsedAt().isEmpty();
 
   // --- MDependencyDefinition ---
-  syn String MDependencyDefinition.targetParentTypeName() = getDependencyDefinition().getTarget().containingTypeDecl().getName();
-  syn String MDependencyDefinition.dependencyMethod() = "add" + capitalize(getDependencyDefinition().getID());
-  syn String MDependencyDefinition.sourceParentTypeName() = getDependencyDefinition().getSource().containingTypeDecl().getName();
-  syn String MDependencyDefinition.internalRelationPrefix() = "_internal_" + getDependencyDefinition().getID();
-  syn nta MEndpointDefinition MDependencyDefinition.targetEndpointDefinition() {
-    return getDependencyDefinition().targetEndpointDefinition().toMustache();
-  }
-
-  // --- MTypeComponent ---
-  syn String MTypeComponent.name() = getTypeComponent().getName();
+  syn String DependencyDefinition.targetParentTypeName() = getTarget().containingTypeDecl().getName();
+  syn String DependencyDefinition.dependencyMethod() = "add" + capitalize(getID());
+  syn String DependencyDefinition.sourceParentTypeName() = getSource().containingTypeDecl().getName();
+  syn String DependencyDefinition.internalRelationPrefix() = "_internal_" + getID();
 
   // --- MTokenComponent ---
-  syn String MTokenComponent.parentTypeName() = getTokenComponent().containingTypeDecl().getName();
-  syn String MTokenComponent.name() = getTokenComponent().getName();
-  syn String MTokenComponent.javaType() = getTokenComponent().effectiveJavaTypeUse().prettyPrint();
-  syn String MTokenComponent.internalName() = getTokenComponent().needProxyToken() ? "_internal_" + name() : externalName();
-  syn String MTokenComponent.externalName() = name();
-  syn MTokenSendDefinition MTokenComponent.normalTokenSendDef() {
-    for (TokenEndpointDefinition endpointDef : getTokenComponent().getTokenEndpointDefinitionList()) {
-      if (endpointDef.shouldSendValue()) {
-        return endpointDef.asSendTokenEndpointDefinition().toMustache();
+  syn String TokenComponent.parentTypeName() = containingTypeDecl().getName();
+  syn String TokenComponent.javaType() = effectiveJavaTypeUse().prettyPrint();
+  syn String TokenComponent.internalName() = needProxyToken() ? "_internal_" + getName() : externalName();
+  syn String TokenComponent.externalName() = getName();
+
+  syn EndpointDefinition TokenComponent.normalTokenSendDef() {
+    for (EndpointTarget target : getTokenEndpointTargetList()) {
+      if (target.isTokenEndpointTarget() && target.containingEndpointDefinition().shouldSendValue()) {
+        return target.containingEndpointDefinition();
       }
     }
     return null;
   }
 
-  // --- toMustache ---
-  syn lazy MRagConnect RagConnect.toMustache() {
-    MRagConnect result = new MRagConnect();
-    result.setRagConnect(this);
-    for (EndpointDefinition def : allEndpointDefinitionList()) {
-      if (def.isReceiveTokenEndpointDefinition()) {
-        result.addTokenReceiveDefinition(def.asReceiveTokenEndpointDefinition().toMustache());
-      } else if (def.isSendTokenEndpointDefinition()) {
-        result.addTokenSendDefinition(def.asSendTokenEndpointDefinition().toMustache());
-      } else if (def.isReceiveTypeEndpointDefinition()) {
-        result.addTypeReceiveDefinition(def.asReceiveTypeEndpointDefinition().toMustache());
-      } else if (def.isSendTypeEndpointDefinition()) {
-        result.addTypeSendDefinition(def.asSendTypeEndpointDefinition().toMustache());
+  syn nta MEndpointDefinition EndpointDefinition.toMustache() {
+    final MEndpointDefinition result;
+    if (getEndpointTarget().isTokenEndpointTarget()) {
+      if (getSend()) {
+        result = new MTokenSendDefinition();
       } else {
-        throw new RuntimeException("Unknown endpoint definition: " + def);
+        result = new MTokenReceiveDefinition();
       }
+    } else if (getEndpointTarget().isTokenEndpointTarget()) {
+      if (getSend()) {
+        result = new MTypeSendDefinition();
+      } else {
+        result = new MTypeReceiveDefinition();
+      }
+    } else {
+      throw new RuntimeException("Unknown endpoint target type for " + this);
     }
-    for (MappingDefinition def : allMappingDefinitions()) {
-      result.addMappingDefinition(def.toMustache());
-    }
-    for (DependencyDefinition def : allDependencyDefinitionList()) {
-      result.addDependencyDefinition(def.toMustache());
+    result.setEndpointDefinition(this);
+    for (MappingDefinition def : effectiveMappings()) {
+      MInnerMappingDefinition inner = new MInnerMappingDefinition();
+      inner.setMappingDefinition(def);
+      result.addInnerMappingDefinition(inner);
     }
+    return result;
+  }
+
+  syn List<TokenComponent> RagConnect.tokenComponentsThatNeedProxy() {
+    List<TokenComponent> result = new ArrayList<>();
     for (TokenComponent token : getProgram().allTokenComponents()) {
       if (token.needProxyToken()) {
-        result.addTokenComponent(token.toMustache());
+        result.add(token);
       }
     }
+    return result;
+  }
+
+  syn List<TypeComponent> RagConnect.rootTypeComponents() {
+    List<TypeComponent> result = new ArrayList<>();
     for (Component child : rootNode.getComponentList()) {
       if (child.isTypeComponent()) {
-        result.addRootTypeComponent(child.asTypeComponent().toMustache());
+        result.add(child.asTypeComponent());
       }
     }
-    // MHandler ::= <ClassName> <Construction> <AttributeName> <FieldName> <InUse:boolean>;
-    result.addHandler(new MHandler("MqttServerHandler", "new MqttServerHandler(\"RagConnectMQTT\")",
-                                   result.mqttHandlerAttribute(), result.mqttHandlerField(), usesMqtt));
-    result.addHandler(new MHandler("RestServerHandler", "new RestServerHandler(\"RagConnectREST\")",
-                                   result.restHandlerAttribute(), result.restHandlerField(), usesRest));
     return result;
   }
 
-  protected void MEndpointDefinition.addInnerMappings() {
-    for (MappingDefinition def : endpointDef().effectiveMappings()) {
-      MInnerMappingDefinition inner = new MInnerMappingDefinition();
-      inner.setMMappingDefinition(def.toMustache());
-      addInnerMappingDefinition(inner);
-    }
-  }
-
-  public abstract MEndpointDefinition EndpointDefinition.toMustache();
-  syn lazy MTokenReceiveDefinition ReceiveTokenEndpointDefinition.toMustache() {
-    MTokenReceiveDefinition result = new MTokenReceiveDefinition();
-    result.setReceiveTokenEndpointDefinition(this);
-    result.addInnerMappings();
-    return result;
-  }
+}
 
-  syn lazy MTokenSendDefinition SendTokenEndpointDefinition.toMustache() {
-    MTokenSendDefinition result = new MTokenSendDefinition();
-    result.setSendTokenEndpointDefinition(this);
-    result.addInnerMappings();
-    return result;
-  }
+aspect OldStuff { // copied unchanged, but should work
+  // --- EndpointDefinition ---
+  syn String EndpointDefinition.idTokenName() = "InternalRagconnectTopicInList";
 
-  syn lazy MTypeReceiveDefinition ReceiveTypeEndpointDefinition.toMustache() {
-    MTypeReceiveDefinition result = new MTypeReceiveDefinition();
-    result.setReceiveTypeEndpointDefinition(this);
-    result.addInnerMappings();
-    return result;
-  }
+  // --- MEndpointDefinition ---
+  syn String MEndpointDefinition.preemptiveExpectedValue();
+  syn String MEndpointDefinition.preemptiveReturn();
+  syn String MEndpointDefinition.firstInputVarName();
+  syn String MEndpointDefinition.parentTypeName() = getEndpointDefinition().parentTypeName();
+  syn String MEndpointDefinition.entityName() = getEndpointDefinition().entityName();
+  syn String MEndpointDefinition.updateMethod();
+  syn String MEndpointDefinition.writeMethod();
+  syn String MEndpointDefinition.getterMethod() = getEndpointDefinition().getterMethod();
 
-  syn lazy MTypeSendDefinition SendTypeEndpointDefinition.toMustache() {
-    MTypeSendDefinition result = new MTypeSendDefinition();
-    result.setSendTypeEndpointDefinition(this);
-    result.addInnerMappings();
-    return result;
-  }
+  // --- MInnerMappingDefinition ---
+  inh String MInnerMappingDefinition.inputVarName();
+  syn String MInnerMappingDefinition.toType() = getMappingDefinition().getToType().prettyPrint();
+  syn String MInnerMappingDefinition.methodName() = getMappingDefinition().methodName();
+  syn String MInnerMappingDefinition.outputVarName() = "result" + methodName();  // we do not need "_" in between here, because methodName begins with one
 
-  syn lazy MMappingDefinition MappingDefinition.toMustache() {
-    MMappingDefinition result = new MMappingDefinition();
-    result.setMappingDefinition(this);
-    return result;
-  }
+  // --- MTokenReceiveDefinition ---
+  eq MTokenReceiveDefinition.preemptiveExpectedValue() = getterMethod() + "()";
+  eq MTokenReceiveDefinition.preemptiveReturn() = "return;";
+  eq MTokenReceiveDefinition.firstInputVarName() = "message";
+  eq MTokenReceiveDefinition.updateMethod() = null;
+  eq MTokenReceiveDefinition.writeMethod() = null;
 
-  syn lazy MDependencyDefinition DependencyDefinition.toMustache() {
-    MDependencyDefinition result = new MDependencyDefinition();
-    result.setDependencyDefinition(this);
-    return result;
-  }
+  // --- MTokenSendDefinition ---
+  eq MTokenSendDefinition.preemptiveExpectedValue() = lastValue();
+  eq MTokenSendDefinition.preemptiveReturn() = "return false;";
+  eq MTokenSendDefinition.firstInputVarName() = getterMethod() + "()";
+  eq MTokenSendDefinition.updateMethod() = "_update_" + tokenName();
+  eq MTokenSendDefinition.writeMethod() = "_writeLastValue_" + tokenName();
 
-  syn lazy MTypeComponent TypeComponent.toMustache() {
-    MTypeComponent result = new MTypeComponent();
-    result.setTypeComponent(this);
-    return result;
-  }
+  // MTypeReceiveDefinition
+  eq MTypeReceiveDefinition.preemptiveExpectedValue() = getterMethod() + "()";
+  eq MTypeReceiveDefinition.preemptiveReturn() = "return;";
+  eq MTypeReceiveDefinition.firstInputVarName() = "message";
+  eq MTypeReceiveDefinition.updateMethod() = null;
+  eq MTypeReceiveDefinition.writeMethod() = null;
 
-  syn lazy MTokenComponent TokenComponent.toMustache() {
-    MTokenComponent result = new MTokenComponent();
-    result.setTokenComponent(this);
-    for (DependencyDefinition def : getDependencySourceDefinitionList()) {
-      result.addDependencyDefinition(def.toMustache());
-    }
-    return result;
-  }
+  // MTypeSendDefinition
+  eq MTypeSendDefinition.preemptiveExpectedValue() = lastValue();
+  eq MTypeSendDefinition.preemptiveReturn() = "return false;";
+  eq MTypeSendDefinition.firstInputVarName() = getterMethod() + "()";
+  eq MTypeSendDefinition.updateMethod() = "_update_" + typeName();
+  eq MTypeSendDefinition.writeMethod() = "_writeLastValue_" + typeName();
 }
 
 aspect AspectGeneration {
@@ -338,10 +267,16 @@ aspect AspectGeneration {
 
   public String RagConnect.generateAspect(String rootNodeName) {
     rootNode = getProgram().resolveTypeDecl(rootNodeName);
-    return toMustache().generateAspect();
+    return generateAspect();
   }
 
-  public String MRagConnect.generateAspect() {
+  public String RagConnect.generateAspect() {
+    // TODO move this to Compiler.java
+    // Handler ::= <ClassName> <Construction> <AttributeName> <FieldName> <InUse:boolean>;
+    this.addHandler(new Handler("MqttServerHandler", "new MqttServerHandler(\"RagConnectMQTT\")",
+                                mqttHandlerAttribute(), mqttHandlerField(), usesMqtt));
+    this.addHandler(new Handler("RestServerHandler", "new RestServerHandler(\"RagConnectREST\")",
+                                restHandlerAttribute(), restHandlerField(), usesRest));
     StringBuilder sb = new StringBuilder();
     com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
       @Override
@@ -357,6 +292,13 @@ aspect AspectGeneration {
           }
         };
       }
+      @Override
+      public Object coerce(Object object) {
+        if (object instanceof Collection) {
+          return new com.github.mustachejava.util.DecoratedCollection((Collection) object);
+        }
+        return super.coerce(object);
+      }
     };
     com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
     mf.setObjectHandler(roh);
@@ -376,11 +318,10 @@ aspect GrammarGeneration {
   }
 
   syn nta Relation DependencyDefinition.getRelationToCreate() {
-    String internalRelationPrefix = toMustache().internalRelationPrefix();
     BidirectionalRelation result = new BidirectionalRelation();
-    NavigableRole left = new ListRole(internalRelationPrefix + "Source");
+    NavigableRole left = new ListRole(internalRelationPrefix() + "Source");
     left.setType(getTarget().containingTypeDecl());
-    NavigableRole right = new ListRole(internalRelationPrefix + "Target");
+    NavigableRole right = new ListRole(internalRelationPrefix() + "Target");
     right.setType(getSource().containingTypeDecl());
     result.setLeft(left);
     result.setRight(right);
@@ -399,15 +340,14 @@ aspect GrammarGeneration {
   syn java.util.Map<TypeDecl, TokenComponent> RagConnect.additionalTokens() {
     java.util.Map<TypeDecl, TokenComponent> result = new java.util.HashMap<>();
     for (EndpointDefinition def : allEndpointDefinitionList()) {
-      if (def.isTypeEndpointDefinition() && def.getTokenToCreate() != null) {
-        result.put(def.asTypeEndpointDefinition().getType().getTypeDecl(), def.getTokenToCreate());
+      if (def.getTokenToCreate() != null) {
+        result.put(def.type().getTypeDecl(), def.getTokenToCreate());
       }
     }
     return result;
   }
 
-  syn TokenComponent EndpointDefinition.getTokenToCreate() = null;
-  eq TypeEndpointDefinition.getTokenToCreate() {
+  syn TokenComponent EndpointDefinition.getTokenToCreate() {
     if (typeIsList() && getIndexBasedListAccess()) {
       TokenComponent result = new TokenComponent();
       result.setName(idTokenName());
@@ -427,7 +367,7 @@ aspect GrammarExtension {
     }
     b.append("<");
     if (!getName().equals("")) {
-      b.append(toMustache().internalName()).append(":");
+      b.append(internalName()).append(":");
     }
     effectiveJavaTypeUse().generateAbstractGrammar(b);
     b.append(">");
diff --git a/ragconnect.base/src/main/jastadd/intermediate/Mappings.jrag b/ragconnect.base/src/main/jastadd/intermediate/Mappings.jrag
index 9d122978ee65307972063cb33e111e951b979569..afdcb102577727ac649a045d5f7f0910a9df30fe 100644
--- a/ragconnect.base/src/main/jastadd/intermediate/Mappings.jrag
+++ b/ragconnect.base/src/main/jastadd/intermediate/Mappings.jrag
@@ -141,7 +141,7 @@ aspect Mappings {
   // --- effectiveMappings ---
   syn java.util.List<MappingDefinition> EndpointDefinition.effectiveMappings() {
     java.util.List<MappingDefinition> result;
-    if (isReceiveTokenEndpointDefinition() || isReceiveTypeEndpointDefinition()) {
+    if (!getSend()) {
       // if no mappings are specified, or if first mapping is not suitable.
       // then prepend the suitable default mapping
       if (getMappingList().isEmpty() || !getMappingList().get(0).getFromType().isByteArray()) {
@@ -151,7 +151,7 @@ aspect Mappings {
       } else {
         result = getMappingList();
       }
-    } else if (isSendTokenEndpointDefinition() || isSendTypeEndpointDefinition()) {
+    } else {
       // if no mappings are specified, or if last mapping is not suitable
       // then append the suitable default mapping
       if (getMappingList().isEmpty() || !getMappingList().get(getMappingList().size() - 1).getToType().isByteArray()) {
@@ -160,8 +160,6 @@ aspect Mappings {
       } else {
         result = getMappingList();
       }
-    } else {
-      throw new RuntimeException("Unknown endpoint definition: " + this);
     }
     return result;
   }
@@ -191,6 +189,12 @@ aspect Mappings {
 
   // --- suitableReceiveDefaultMapping ---
   syn DefaultMappingDefinition EndpointDefinition.suitableReceiveDefaultMapping() {
+    if (getEndpointTarget().isTypeEndpointTarget()) {
+      try {
+        TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
+        return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultBytesToListTreeMapping(typeDecl.getName()) : ragconnect().defaultBytesToTreeMapping(typeDecl.getName());
+      } catch (Exception ignore) {}
+    }
     switch (targetTypeName()) {
       case "boolean":
       case "Boolean": return ragconnect().defaultBytesToBooleanMapping();
@@ -217,16 +221,15 @@ aspect Mappings {
         return null;
     }
   }
-  eq TypeEndpointDefinition.suitableReceiveDefaultMapping() {
-    try {
-      TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
-      return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultBytesToListTreeMapping(typeDecl.getName()) : ragconnect().defaultBytesToTreeMapping(typeDecl.getName());
-    } catch (Exception ignore) {}
-    return super.suitableReceiveDefaultMapping();
-  }
 
   // --- suitableSendDefaultMapping ---
   syn DefaultMappingDefinition EndpointDefinition.suitableSendDefaultMapping() {
+    if (getEndpointTarget().isTypeEndpointTarget()) {
+      try {
+        TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
+        return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultListTreeToBytesMapping() : ragconnect().defaultTreeToBytesMapping(typeDecl.getName());
+      } catch (Exception ignore) {}
+    }
     switch (targetTypeName()) {
       case "boolean":
       case "Boolean": return ragconnect().defaultBooleanToBytesMapping();
@@ -253,36 +256,22 @@ aspect Mappings {
         return null;
     }
   }
-  eq TypeEndpointDefinition.suitableSendDefaultMapping() {
-    try {
-      TypeDecl typeDecl = program().resolveTypeDecl(targetTypeName());
-      return typeIsList() && !getIndexBasedListAccess() ? ragconnect().defaultListTreeToBytesMapping() : ragconnect().defaultTreeToBytesMapping(typeDecl.getName());
-    } catch (Exception ignore) {}
-    return super.suitableSendDefaultMapping();
-  }
 
   // --- targetTypeName ---
-  syn String EndpointDefinition.targetTypeName();
-  eq ReceiveTokenEndpointDefinition.targetTypeName() {
-    return getMappingList().isEmpty() ?
-           getToken().effectiveJavaTypeUse().getName() :
-           getMappingList().get(0).getFromType().prettyPrint();
-  }
-  eq ReceiveTypeEndpointDefinition.targetTypeName() {
-    return getMappingList().isEmpty() ?
-           getType().getTypeDecl().getName() :
-           getMappingList().get(0).getFromType().prettyPrint();
-  }
-  eq SendTokenEndpointDefinition.targetTypeName() {
-    return getMappingList().isEmpty() ?
-           getToken().effectiveJavaTypeUse().getName() :
-           getMappingList().get(getMappingList().size() - 1).getToType().prettyPrint();
-  }
-  eq SendTypeEndpointDefinition.targetTypeName() {
-    return getMappingList().isEmpty() ?
-           getType().getTypeDecl().getName() :
-           getMappingList().get(getMappingList().size() - 1).getToType().prettyPrint();
+  syn String EndpointDefinition.targetTypeName() {
+    if (getMappingList().isEmpty()) {
+      return getEndpointTarget().targetTypeName();
+    } else {
+      if (getSend()) {
+        return getMappingList().get(0).getFromType().prettyPrint();
+      } else {
+        return getMappingList().get(getMappingList().size() - 1).getToType().prettyPrint();
+      }
+    }
   }
+  syn String EndpointTarget.targetTypeName();
+  eq TokenEndpointTarget.targetTypeName() = getToken().effectiveJavaTypeUse().getName();
+  eq TypeEndpointTarget.targetTypeName() = getType().getTypeDecl().getName();
 
 //  eq ReceiveFromRestDefinition.suitableDefaultMapping() {
 //    String typeName = getMappingList().isEmpty() ?
diff --git a/ragconnect.base/src/main/jastadd/intermediate/MustacheNodes.relast b/ragconnect.base/src/main/jastadd/intermediate/MustacheNodes.relast
index 8255cfe5ad9e67e00e53e95b4ddc110a480dce28..08b5b5027f413f873c561dd4492ad0c32eb6e3d2 100644
--- a/ragconnect.base/src/main/jastadd/intermediate/MustacheNodes.relast
+++ b/ragconnect.base/src/main/jastadd/intermediate/MustacheNodes.relast
@@ -1,4 +1,4 @@
-MRagConnect ::= TokenReceiveDefinition:MTokenReceiveDefinition* TokenSendDefinition:MTokenSendDefinition* TypeReceiveDefinition:MTypeReceiveDefinition* TypeSendDefinition:MTypeSendDefinition* MappingDefinition:MMappingDefinition* DependencyDefinition:MDependencyDefinition* RootTypeComponent:MTypeComponent* TokenComponent:MTokenComponent* Handler:MHandler*;
+//MRagConnect ::= TokenReceiveDefinition:MTokenReceiveDefinition* TokenSendDefinition:MTokenSendDefinition* TypeReceiveDefinition:MTypeReceiveDefinition* TypeSendDefinition:MTypeSendDefinition* ;
 
 abstract MEndpointDefinition ::= InnerMappingDefinition:MInnerMappingDefinition*;
 abstract MTokenEndpointDefinition : MEndpointDefinition;
@@ -8,21 +8,17 @@ abstract MTypeEndpointDefinition : MEndpointDefinition;
 MTypeReceiveDefinition : MTypeEndpointDefinition;
 MTypeSendDefinition : MTypeEndpointDefinition;
 
-MMappingDefinition;
+//MMappingDefinition;
 MInnerMappingDefinition;
-MDependencyDefinition;
-MTypeComponent;
-MTokenComponent;
-MHandler ::= <ClassName> <Construction> <AttributeName> <FieldName> <InUse:boolean>;
+//MDependencyDefinition;
+//MTypeComponent;
+//MTokenComponent;
 
-rel MRagConnect.RagConnect -> RagConnect;
-rel MInnerMappingDefinition.MMappingDefinition -> MMappingDefinition;
-rel MTokenReceiveDefinition.ReceiveTokenEndpointDefinition -> ReceiveTokenEndpointDefinition;
-rel MTokenSendDefinition.SendTokenEndpointDefinition -> SendTokenEndpointDefinition;
-rel MTypeReceiveDefinition.ReceiveTypeEndpointDefinition -> ReceiveTypeEndpointDefinition;
-rel MTypeSendDefinition.SendTypeEndpointDefinition -> SendTypeEndpointDefinition;
-rel MMappingDefinition.MappingDefinition -> MappingDefinition;
-rel MDependencyDefinition.DependencyDefinition -> DependencyDefinition;
-rel MTypeComponent.TypeComponent -> TypeComponent;
-rel MTokenComponent.TokenComponent -> TokenComponent;
-rel MTokenComponent.DependencyDefinition* -> MDependencyDefinition;
+//rel MRagConnect.RagConnect -> RagConnect;
+rel MInnerMappingDefinition.MappingDefinition -> MappingDefinition;
+rel MEndpointDefinition.EndpointDefinition -> EndpointDefinition;
+//rel MMappingDefinition.MappingDefinition -> MappingDefinition;
+//rel MDependencyDefinition.DependencyDefinition -> DependencyDefinition;
+//rel MTypeComponent.TypeComponent -> TypeComponent;
+//rel MTokenComponent.TokenComponent -> TokenComponent;
+//rel MTokenComponent.DependencyDefinition* -> MDependencyDefinition;
diff --git a/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag b/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag
index 04b9cf89c248c39740677c88835b56c5325493bf..9b85aecf2391780d05cbd8dab2b2c162678f171a 100644
--- a/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag
+++ b/ragconnect.base/src/main/jastadd/intermediate2mustache/MustacheNodesToYAML.jrag
@@ -1,212 +1,212 @@
-aspect MustacheNodesToYAML {
-  syn Document MRagConnect.toYAML() {
-    Document doc = new Document();
-    MappingElement root = new MappingElement();
-    root.put("rootNodeName", rootNodeName());
-    root.put("closeMethod", closeMethod());
-    root.put("usesMqtt", usesMqtt);
-    root.put("usesRest", usesRest);
-    // mqtt
-    root.put("mqttHandlerField", mqttHandlerField());
-    root.put("mqttHandlerAttribute", mqttHandlerAttribute());
-    root.put("mqttSetupWaitUntilReadyMethod", mqttSetupWaitUntilReadyMethod());
-
-    // rootTypeComponents
-    ListElement rootTypeComponents = new ListElement();
-    for (MTypeComponent comp : getRootTypeComponentList()) {
-      MappingElement inner = new MappingElement();
-      inner.put("first", comp.isFirst());
-      inner.put("name", comp.name());
-      rootTypeComponents.addElement(inner);
-    }
-    root.put("RootTypeComponents", rootTypeComponents);
-
-    // rest
-    root.put("restHandlerField", restHandlerField());
-    root.put("restHandlerAttribute", restHandlerAttribute());
-
-    // TokenReceiveDefinitions
-    ListElement receiveDefinitions = new ListElement();
-    for (MTokenReceiveDefinition def : getTokenReceiveDefinitionList()) {
-      receiveDefinitions.addElement(def.toYAML());
-    }
-    root.put("TokenReceiveDefinitions", receiveDefinitions);
-
-    // TokenSendDefinitions
-    ListElement sendDefinitions = new ListElement();
-    for (MTokenSendDefinition def : getTokenSendDefinitionList()) {
-      sendDefinitions.addElement(def.toYAML());
-    }
-    root.put("TokenSendDefinitions", sendDefinitions);
-
-    // TypeReceiveDefinitions
-    ListElement typeReceiveDefinitions = new ListElement();
-    for (MTypeReceiveDefinition def : getTypeReceiveDefinitionList()) {
-      typeReceiveDefinitions.addElement(def.toYAML());
-    }
-    root.put("TypeReceiveDefinitions", typeReceiveDefinitions);
-
-    // TypeSendDefinitions
-    ListElement typeSendDefinitions = new ListElement();
-    for (MTypeSendDefinition def : getTypeSendDefinitionList()) {
-      typeSendDefinitions.addElement(def.toYAML());
-    }
-    root.put("TypeSendDefinitions", typeSendDefinitions);
-
-    // MappingDefinitions
-    ListElement mappingDefinitions = new ListElement();
-    for (MMappingDefinition def : getMappingDefinitionList()) {
-      mappingDefinitions.addElement(def.toYAML());
-    }
-    root.put("MappingDefinitions", mappingDefinitions);
-
-    // DependencyDefinitions
-    ListElement dependencyDefinitions = new ListElement();
-    for (MDependencyDefinition def : getDependencyDefinitionList()) {
-      dependencyDefinitions.addElement(def.toYAML());
-    }
-    root.put("DependencyDefinitions", dependencyDefinitions);
-
-    // TokenComponents
-    ListElement tokenComponents = new ListElement();
-    for (MTokenComponent comp : getTokenComponentList()) {
-      tokenComponents.addElement(comp.toYAML());
-    }
-    root.put("TokenComponents", tokenComponents);
-
-    // Handlers
-    ListElement handlers = new ListElement();
-    for (MHandler handler : getHandlerList()) {
-      handlers.add(handler.toYAML()
-                          .put("rootTokenComponents", rootTypeComponents.treeCopy()) );
-    }
-    root.put("Handlers", handlers);
-
-    doc.setRootElement(root);
-    return doc;
-  }
-
-  syn MappingElement MEndpointDefinition.toYAML() {
-    MappingElement result = new MappingElement();
-    result.put("parentTypeName", parentTypeName());
-    result.put("connectMethod", connectMethod());
-    result.put("connectParameterName", connectParameterName());
-    result.put("lastDefinitionToType", lastDefinitionToType());
-    result.put("preemptiveReturn", preemptiveReturn());
-    result.put("alwaysApply", alwaysApply());
-    result.put("condition",
-    condition().replace("\"", "\\\"").replace("\n", "\\n"));
-    result.put("lastResult", lastResult());
-    result.put("tokenName", tokenName());
-    result.put("InnerMappingDefinitions", innerMappingDefinitionsAsListElement());
-    return result;
-  }
-
-  syn MappingElement MTokenReceiveDefinition.toYAML() {
-    MappingElement result = super.toYAML();
-    result.put("loggingEnabledForReads", loggingEnabledForReads);
-    return result;
-  }
-
-  syn MappingElement MTokenSendDefinition.toYAML() {
-    MappingElement result = super.toYAML();
-    result.put("sender", sender());
-    result.put("lastValue", lastValue());
-    result.put("loggingEnabledForWrites", loggingEnabledForWrites);
-    result.put("updateMethod", updateMethod());
-    result.put("writeMethod", writeMethod());
-    result.put("tokenResetMethod", tokenResetMethod());
-    return result;
-  }
-
-  syn MappingElement MTypeReceiveDefinition.toYAML() {
-    MappingElement result = super.toYAML();
-    result.put("typeIsList", typeIsList());
-    result.put("loggingEnabledForReads", loggingEnabledForReads);
-    return result;
-  }
-
-  syn MappingElement MTypeSendDefinition.toYAML() {
-    MappingElement result = super.toYAML();
-    result.put("typeIsList", typeIsList());
-    result.put("sender", sender());
-    result.put("lastValue", lastValue());
-    result.put("loggingEnabledForWrites", loggingEnabledForWrites);
-    result.put("updateMethod", updateMethod());
-    result.put("writeMethod", writeMethod());
-    result.put("tokenResetMethod", tokenResetMethod());
-    return result;
-  }
-
-  syn Element MMappingDefinition.toYAML() {
-    MappingElement result = new MappingElement();
-    result.put("toType", toType());
-    result.put("methodName", methodName());
-    result.put("fromType", fromType());
-    result.put("fromVariableName", fromVariableName());
-    result.put("content",
-        content().replace("\"", "\\\"").replace("\n", "\\n"));
-    return result;
-  }
-
-  syn Element MDependencyDefinition.toYAML() {
-    MappingElement result = new MappingElement();
-    result.put("targetParentTypeName", targetParentTypeName());
-    result.put("dependencyMethod", dependencyMethod());
-    result.put("sourceParentTypeName", sourceParentTypeName());
-    result.put("internalRelationPrefix", internalRelationPrefix());
-    return result;
-  }
-
-  syn Element MTokenComponent.toYAML() {
-    MappingElement result = new MappingElement();
-    result.put("parentTypeName", parentTypeName());
-    result.put("name", name());
-    result.put("javaType", javaType());
-    result.put("internalName", internalName());
-    ListElement dependencyDefinitions = new ListElement();
-    for (MDependencyDefinition def : getDependencyDefinitionList()) {
-      MappingElement inner = new MappingElement();
-      inner.put("targetParentTypeName", def.targetParentTypeName());
-      inner.put("internalRelationPrefix", def.internalRelationPrefix());
-      MappingElement targetEndpointDefinition = new MappingElement();
-    targetEndpointDefinition.put("updateMethod", def.targetEndpointDefinition().updateMethod());
-    targetEndpointDefinition.put("writeMethod", def.targetEndpointDefinition().writeMethod());
-      inner.put("targetEndpointDefinition", targetEndpointDefinition);
-      dependencyDefinitions.addElement(inner);
-    }
-    result.put("DependencyDefinitions", dependencyDefinitions);
-    return result;
-  }
-
-  ListElement MEndpointDefinition.innerMappingDefinitionsAsListElement() {
-    ListElement innerMappingDefinitions = new ListElement();
-    for (MInnerMappingDefinition def : getInnerMappingDefinitionList()) {
-      MappingElement inner = new MappingElement();
-      inner.put("toType", def.toType());
-      inner.put("methodName", def.methodName());
-      inner.put("inputVarName", def.inputVarName());
-      inner.put("outputVarName", def.outputVarName());
-      inner.put("last", def.isLast());
-      innerMappingDefinitions.addElement(inner);
-    }
-    return innerMappingDefinitions;
-  }
-
-  syn MappingElement MHandler.toYAML() {
-    MappingElement result = new MappingElement();
-    result.put("ClassName", getClassName());
-    result.put("Construction", getConstruction());
-    result.put("AttributeName", getAttributeName());
-    result.put("FieldName", getFieldName());
-    result.put("InUse", getInUse());
-    return result;
-  }
-}
-
-aspect Navigation {
-  eq Document.getChild().program() = null;
-  eq Document.getChild().ragconnect() = null;
-  eq Document.getChild().containedFile() = null;
-  eq Document.containedFileName() = getFileName();
-}
+// aspect MustacheNodesToYAML {
+//   syn Document MRagConnect.toYAML() {
+//     Document doc = new Document();
+//     MappingElement root = new MappingElement();
+//     root.put("rootNodeName", rootNodeName());
+//     root.put("closeMethod", closeMethod());
+//     root.put("usesMqtt", usesMqtt);
+//     root.put("usesRest", usesRest);
+//     // mqtt
+//     root.put("mqttHandlerField", mqttHandlerField());
+//     root.put("mqttHandlerAttribute", mqttHandlerAttribute());
+//     root.put("mqttSetupWaitUntilReadyMethod", mqttSetupWaitUntilReadyMethod());
+//
+//     // rootTypeComponents
+//     ListElement rootTypeComponents = new ListElement();
+//     for (MTypeComponent comp : getRootTypeComponentList()) {
+//       MappingElement inner = new MappingElement();
+//       inner.put("first", comp.isFirst());
+//       inner.put("name", comp.name());
+//       rootTypeComponents.addElement(inner);
+//     }
+//     root.put("RootTypeComponents", rootTypeComponents);
+//
+//     // rest
+//     root.put("restHandlerField", restHandlerField());
+//     root.put("restHandlerAttribute", restHandlerAttribute());
+//
+//     // TokenReceiveDefinitions
+//     ListElement receiveDefinitions = new ListElement();
+//     for (MTokenReceiveDefinition def : getTokenReceiveDefinitionList()) {
+//       receiveDefinitions.addElement(def.toYAML());
+//     }
+//     root.put("TokenReceiveDefinitions", receiveDefinitions);
+//
+//     // TokenSendDefinitions
+//     ListElement sendDefinitions = new ListElement();
+//     for (MTokenSendDefinition def : getTokenSendDefinitionList()) {
+//       sendDefinitions.addElement(def.toYAML());
+//     }
+//     root.put("TokenSendDefinitions", sendDefinitions);
+//
+//     // TypeReceiveDefinitions
+//     ListElement typeReceiveDefinitions = new ListElement();
+//     for (MTypeReceiveDefinition def : getTypeReceiveDefinitionList()) {
+//       typeReceiveDefinitions.addElement(def.toYAML());
+//     }
+//     root.put("TypeReceiveDefinitions", typeReceiveDefinitions);
+//
+//     // TypeSendDefinitions
+//     ListElement typeSendDefinitions = new ListElement();
+//     for (MTypeSendDefinition def : getTypeSendDefinitionList()) {
+//       typeSendDefinitions.addElement(def.toYAML());
+//     }
+//     root.put("TypeSendDefinitions", typeSendDefinitions);
+//
+//     // MappingDefinitions
+//     ListElement mappingDefinitions = new ListElement();
+//     for (MMappingDefinition def : getMappingDefinitionList()) {
+//       mappingDefinitions.addElement(def.toYAML());
+//     }
+//     root.put("MappingDefinitions", mappingDefinitions);
+//
+//     // DependencyDefinitions
+//     ListElement dependencyDefinitions = new ListElement();
+//     for (MDependencyDefinition def : getDependencyDefinitionList()) {
+//       dependencyDefinitions.addElement(def.toYAML());
+//     }
+//     root.put("DependencyDefinitions", dependencyDefinitions);
+//
+//     // TokenComponents
+//     ListElement tokenComponents = new ListElement();
+//     for (MTokenComponent comp : getTokenComponentList()) {
+//       tokenComponents.addElement(comp.toYAML());
+//     }
+//     root.put("TokenComponents", tokenComponents);
+//
+//     // Handlers
+//     ListElement handlers = new ListElement();
+//     for (MHandler handler : getHandlerList()) {
+//       handlers.add(handler.toYAML()
+//                           .put("rootTokenComponents", rootTypeComponents.treeCopy()) );
+//     }
+//     root.put("Handlers", handlers);
+//
+//     doc.setRootElement(root);
+//     return doc;
+//   }
+//
+//   syn MappingElement MEndpointDefinition.toYAML() {
+//     MappingElement result = new MappingElement();
+//     result.put("parentTypeName", parentTypeName());
+//     result.put("connectMethod", connectMethod());
+//     result.put("connectParameterName", connectParameterName());
+//     result.put("lastDefinitionToType", lastDefinitionToType());
+//     result.put("preemptiveReturn", preemptiveReturn());
+//     result.put("alwaysApply", alwaysApply());
+//     result.put("condition",
+//     condition().replace("\"", "\\\"").replace("\n", "\\n"));
+//     result.put("lastResult", lastResult());
+//     result.put("tokenName", tokenName());
+//     result.put("InnerMappingDefinitions", innerMappingDefinitionsAsListElement());
+//     return result;
+//   }
+//
+//   syn MappingElement MTokenReceiveDefinition.toYAML() {
+//     MappingElement result = super.toYAML();
+//     result.put("loggingEnabledForReads", loggingEnabledForReads);
+//     return result;
+//   }
+//
+//   syn MappingElement MTokenSendDefinition.toYAML() {
+//     MappingElement result = super.toYAML();
+//     result.put("sender", sender());
+//     result.put("lastValue", lastValue());
+//     result.put("loggingEnabledForWrites", loggingEnabledForWrites);
+//     result.put("updateMethod", updateMethod());
+//     result.put("writeMethod", writeMethod());
+//     result.put("tokenResetMethod", tokenResetMethod());
+//     return result;
+//   }
+//
+//   syn MappingElement MTypeReceiveDefinition.toYAML() {
+//     MappingElement result = super.toYAML();
+//     result.put("typeIsList", typeIsList());
+//     result.put("loggingEnabledForReads", loggingEnabledForReads);
+//     return result;
+//   }
+//
+//   syn MappingElement MTypeSendDefinition.toYAML() {
+//     MappingElement result = super.toYAML();
+//     result.put("typeIsList", typeIsList());
+//     result.put("sender", sender());
+//     result.put("lastValue", lastValue());
+//     result.put("loggingEnabledForWrites", loggingEnabledForWrites);
+//     result.put("updateMethod", updateMethod());
+//     result.put("writeMethod", writeMethod());
+//     result.put("tokenResetMethod", tokenResetMethod());
+//     return result;
+//   }
+//
+//   syn Element MMappingDefinition.toYAML() {
+//     MappingElement result = new MappingElement();
+//     result.put("toType", toType());
+//     result.put("methodName", methodName());
+//     result.put("fromType", fromType());
+//     result.put("fromVariableName", fromVariableName());
+//     result.put("content",
+//         content().replace("\"", "\\\"").replace("\n", "\\n"));
+//     return result;
+//   }
+//
+//   syn Element MDependencyDefinition.toYAML() {
+//     MappingElement result = new MappingElement();
+//     result.put("targetParentTypeName", targetParentTypeName());
+//     result.put("dependencyMethod", dependencyMethod());
+//     result.put("sourceParentTypeName", sourceParentTypeName());
+//     result.put("internalRelationPrefix", internalRelationPrefix());
+//     return result;
+//   }
+//
+//   syn Element MTokenComponent.toYAML() {
+//     MappingElement result = new MappingElement();
+//     result.put("parentTypeName", parentTypeName());
+//     result.put("name", name());
+//     result.put("javaType", javaType());
+//     result.put("internalName", internalName());
+//     ListElement dependencyDefinitions = new ListElement();
+//     for (MDependencyDefinition def : getDependencyDefinitionList()) {
+//       MappingElement inner = new MappingElement();
+//       inner.put("targetParentTypeName", def.targetParentTypeName());
+//       inner.put("internalRelationPrefix", def.internalRelationPrefix());
+//       MappingElement targetEndpointDefinition = new MappingElement();
+//     targetEndpointDefinition.put("updateMethod", def.targetEndpointDefinition().updateMethod());
+//     targetEndpointDefinition.put("writeMethod", def.targetEndpointDefinition().writeMethod());
+//       inner.put("targetEndpointDefinition", targetEndpointDefinition);
+//       dependencyDefinitions.addElement(inner);
+//     }
+//     result.put("DependencyDefinitions", dependencyDefinitions);
+//     return result;
+//   }
+//
+//   ListElement MEndpointDefinition.innerMappingDefinitionsAsListElement() {
+//     ListElement innerMappingDefinitions = new ListElement();
+//     for (MInnerMappingDefinition def : getInnerMappingDefinitionList()) {
+//       MappingElement inner = new MappingElement();
+//       inner.put("toType", def.toType());
+//       inner.put("methodName", def.methodName());
+//       inner.put("inputVarName", def.inputVarName());
+//       inner.put("outputVarName", def.outputVarName());
+//       inner.put("last", def.isLast());
+//       innerMappingDefinitions.addElement(inner);
+//     }
+//     return innerMappingDefinitions;
+//   }
+//
+//   syn MappingElement MHandler.toYAML() {
+//     MappingElement result = new MappingElement();
+//     result.put("ClassName", getClassName());
+//     result.put("Construction", getConstruction());
+//     result.put("AttributeName", getAttributeName());
+//     result.put("FieldName", getFieldName());
+//     result.put("InUse", getInUse());
+//     return result;
+//   }
+// }
+//
+// aspect Navigation {
+//   eq Document.getChild().program() = null;
+//   eq Document.getChild().ragconnect() = null;
+//   eq Document.getChild().containedFile() = null;
+//   eq Document.containedFileName() = getFileName();
+// }
diff --git a/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag b/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag
index faaf35ad579259148d06fc7d2f8975f740f2730b..4d9cd9d22f0540866e59e0e6a9b817bd2568f6f5 100644
--- a/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag
+++ b/ragconnect.base/src/main/jastadd/parser/ParserRewrites.jrag
@@ -1,68 +1,24 @@
 aspect ParserRewrites {
-  rewrite SendUntypedEndpointDefinition {
+  rewrite UntypedEndpointTarget {
     when (tryGloballyResolveTypeComponentByToken(getTokenOrType()) != null)
-    to SendTypeEndpointDefinition {
-      SendTypeEndpointDefinition result = new SendTypeEndpointDefinition();
-      result.applyFrom(this);
-      result.setIndexBasedListAccess(this.getIndexed());
+    to TypeEndpointTarget {
+      TypeEndpointTarget result = new TypeEndpointTarget();
+      result.setType(TypeComponent.createRef(this.getTokenOrType()));
       return result;
     }
-  }
-
-  rewrite ReceiveUntypedEndpointDefinition {
-    when (tryGloballyResolveTypeComponentByToken(getTokenOrType()) != null)
-    to ReceiveTypeEndpointDefinition {
-      ReceiveTypeEndpointDefinition result = new ReceiveTypeEndpointDefinition();
-      result.applyFrom(this);
-      result.setWithAdd(this.getWithAdd());
-      result.setIndexBasedListAccess(this.getIndexed());
-      return result;
-    }
-  }
-
-  rewrite SendUntypedEndpointDefinition {
-    when (tryGloballyResolveTokenComponentByToken(getTokenOrType()) != null)
-    to SendTokenEndpointDefinition {
-      SendTokenEndpointDefinition result = new SendTokenEndpointDefinition();
-      result.applyFrom(this);
-      return result;
-    }
-  }
-
-  rewrite ReceiveUntypedEndpointDefinition {
     when (tryGloballyResolveTokenComponentByToken(getTokenOrType()) != null)
-    to ReceiveTokenEndpointDefinition {
-      ReceiveTokenEndpointDefinition result = new ReceiveTokenEndpointDefinition();
-      result.applyFrom(this);
+    to TokenEndpointTarget {
+      TokenEndpointTarget result = new TokenEndpointTarget();
+      result.setToken(TokenComponent.createRef(this.getTokenOrType()));
       return result;
     }
   }
 
-  protected void TypeEndpointDefinition.applyFrom(UntypedEndpointDefinition def) {
-    this.setAlwaysApply(def.getAlwaysApply());
-    this.setType(TypeComponent.createRef(def.getTokenOrType()));
-    this.moveMappingsFrom(def);
-  }
-
-  protected void TokenEndpointDefinition.applyFrom(UntypedEndpointDefinition def) {
-    this.setAlwaysApply(def.getAlwaysApply());
-    this.setToken(TokenComponent.createRef(def.getTokenOrType()));
-    this.moveMappingsFrom(def);
-  }
-
-  protected void EndpointDefinition.moveMappingsFrom(UntypedEndpointDefinition def) {
-    // can safely iterate over list as we get an unmodifyable list
-    for (MappingDefinition mapping : def.getMappingList().toArray(new MappingDefinition[0])) {
-      def.removeMapping(mapping);
-      this.addMapping(mapping);
-    }
-  }
-
-  private void UntypedEndpointDefinition.clearMappings() {
-  }
-
-  eq UntypedEndpointDefinition.targetTypeName() = "<unknown>";
-  syn MEndpointDefinition UntypedEndpointDefinition.toMustache() {
-    throw new RuntimeException("UntypedEndpoint can not be transformed using toMustache!");
-  }
+  eq UntypedEndpointTarget.senderName() = "<untyped.senderName>";
+  eq UntypedEndpointTarget.getterMethod() = "<untyped.getterMethod>";
+  eq UntypedEndpointTarget.parentTypeName() = "<untyped.parentTypeName>";
+  eq UntypedEndpointTarget.entityName() = "<untyped.entityName>";
+  eq UntypedEndpointTarget.isAlreadyDefined() = false;
+  eq UntypedEndpointTarget.entityIsNormalAttribute() = false;
+  eq UntypedEndpointTarget.targetTypeName() = "<untyped.targetTypeName>";
 }
diff --git a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
index 49123081a51d8bfc0ac104cf700ff5f4ea29aada..5ddef630253006a13e64ea84cd4df30dc4b6aa2b 100644
--- a/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
+++ b/ragconnect.base/src/main/jastadd/parser/RagConnect.parser
@@ -31,9 +31,9 @@ ConnectSpecificationFile connect_specification_file
     boolean indexBasedListAccess, boolean withAdd) {
       EndpointDefinition result = new EndpointDefinition();
       result.setSend(send);
-      result.setIndexedBasedListAccess(indexBasedListAccess);
+      result.setIndexBasedListAccess(indexBasedListAccess);
       result.setWithAdd(withAdd);
-      result.setTarget(new UntypedEndpointTarget(type_name + "." + child_name));
+      result.setEndpointTarget(new UntypedEndpointTarget(type_name + "." + child_name));
       return result;
     }
 :} ;
diff --git a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
index 915d9f92d49cf3a847f05d0b23393bce1832fc1a..b07429e686a7f1827f78ac0f43e7a9cb2c1893db 100644
--- a/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
+++ b/ragconnect.base/src/main/java/org/jastadd/ragconnect/compiler/Compiler.java
@@ -79,11 +79,12 @@ public class Compiler extends AbstractCompiler {
     }
 
     if (optionPrintYaml.value()) {
-      ASTNode.rootNode = ragConnect.getProgram().resolveTypeDecl(optionRootNode.value());
-      String yamlContent = ragConnect.toMustache().toYAML().prettyPrint();
-      System.out.println(yamlContent);
-      writeToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.yml"), yamlContent);
-      return 0;
+      System.err.println("Currently unsupported option!");
+//      ASTNode.rootNode = ragConnect.getProgram().resolveTypeDecl(optionRootNode.value());
+//      String yamlContent = ragConnect.toMustache().toYAML().prettyPrint();
+//      System.out.println(yamlContent);
+//      writeToFile(getConfiguration().outputDir().toPath().resolve("RagConnect.yml"), yamlContent);
+      return 1;
     }
 
     LOGGER.fine("Writing output files");
diff --git a/ragconnect.base/src/main/resources/ragconnect.mustache b/ragconnect.base/src/main/resources/ragconnect.mustache
index dd509aa53b34e56f425777c16f5f9f3d34c2fc7a..8b3ae7d799f7da27ca7be4117056e1cb74299ebd 100644
--- a/ragconnect.base/src/main/resources/ragconnect.mustache
+++ b/ragconnect.base/src/main/resources/ragconnect.mustache
@@ -32,9 +32,9 @@ aspect RagConnect {
   {{> dependencyDefinition}}
   {{/DependencyDefinitions}}
 
-  {{#TokenComponents}}
+  {{#tokenComponentsThatNeedProxy}}
   {{> tokenComponent}}
-  {{/TokenComponents}}
+  {{/tokenComponentsThatNeedProxy}}
 
   {{> ListAspect}}