diff --git a/build.gradle b/build.gradle
index db9f3380a3a243bc376cd56697d83fb4c37febbe..ae22d051ebfedf9a99740f119d21ae32b995f224 100644
--- a/build.gradle
+++ b/build.gradle
@@ -93,7 +93,7 @@ task ragConnect(type: JavaExec) {
             '--logReads',
             '--logWrites',
             '--verbose',
-            '--rootNode=A',
+            '--rootNode=Root',
             '--incremental=param,debug',
             "--tracing=cache,flush"
     ])
diff --git a/libs/relast.jar b/libs/relast.jar
index b1a7542048dd1611db7f479307b0285efd8bb1f6..d54fee6e9cedf558f2630db72c2c67533e7c2a02 100644
Binary files a/libs/relast.jar and b/libs/relast.jar differ
diff --git a/src/main/jastadd/MinimalModel.connect b/src/main/jastadd/MinimalModel.connect
index c7f1af635e09d9b999c72930ae2a1e70639a24ac..1015d1ee1e1343b9107ec9cf328a6425c48fac79 100644
--- a/src/main/jastadd/MinimalModel.connect
+++ b/src/main/jastadd/MinimalModel.connect
@@ -1,3 +1,4 @@
+// --- simple case ---
 receive A.Input ;
 send A.OutputOnA ;
 send B.OutputOnB using Transformation ;
@@ -14,3 +15,7 @@ Transformation maps String s to String {:
 A.OutputOnA canDependOn A.Input as dependencyA ;
 B.OutputOnB canDependOn A.Input as dependencyB ;
 C.OutputOnC canDependOn A.Input as dependencyC ;
+
+// --- relational case ---
+send tree SenderRoot.Alfa ;
+receive tree ReceiverRoot.Alfa ;
diff --git a/src/main/jastadd/MinimalModel.jrag b/src/main/jastadd/MinimalModel.jrag
index c684edbe07795bb53e1131bdbaf533cd584da553..41315d6c159c63b7ee136693ec4afec62345e2ed 100644
--- a/src/main/jastadd/MinimalModel.jrag
+++ b/src/main/jastadd/MinimalModel.jrag
@@ -10,4 +10,46 @@ aspect Computation {
   eq A.getC().input() = getInput();
 
   syn D A.getD() = new D().setID("dd" + getInput());
+  syn Alfa SenderRoot.getAlfa() {
+    Alfa result = new Alfa();
+    for (int i = 0; i < 4; i++) {
+      result.addEcho(new Echo().setID(i));
+      result.addFoxtrot(new Foxtrot().setID(i));
+      result.addGolf(new Golf().setID(i));
+    }
+    // rel Alfa.MyBravo -> Bravo ;
+    result.setMyBravo(getBravo(getInput()));
+    // rel Alfa.MultiBravo* -> Bravo ;
+    result.addMultiBravo(getBravo(getInput()));
+    result.addMultiBravo(getBravo((getInput() + 1)));
+
+    // rel Alfa.MidiDelta <-> Delta.MidiAlfa? ;
+    result.setMidiDelta(getDelta(getInput()));
+
+    // rel Alfa.MyEcho -> Echo ;
+    result.setMyEcho(result.getEcho(getInput()));
+    // rel Alfa.MultiEcho* -> Echo ;
+    result.addMultiEcho(result.getEcho(getInput()));
+    result.addMultiEcho(result.getEcho(getInput() + 1));
+
+    // rel Foxtrot.MyAlfa? -> Alfa ;
+    result.getFoxtrot(getInput()).setMyAlfa(result);
+
+    // rel Alfa.MidiGolf <-> Golf.MidiAlfa? ;
+    result.setMidiGolf(result.getGolf(getInput()));
+
+    // rel Alfa.MyHotel -> Hotel ;
+    result.setMyHotel(getSenderSubTree().getHotel(getInput()));
+    // rel Alfa.MultiHotel* -> Hotel ;
+    result.addMultiHotel(getSenderSubTree().getHotel(getInput()));
+    result.addMultiHotel(getSenderSubTree().getHotel((getInput() + 1)));
+    return result;
+  }
+}
+
+aspect NameResolution {
+  @Override
+  protected String Nameable.customID() {
+    return getClass().getSimpleName() + getID();
+  }
 }
diff --git a/src/main/jastadd/MinimalModel.relast b/src/main/jastadd/MinimalModel.relast
index 1df3cc07e098d21ac34238697ba7afdeecdd5067..f5852950d9a9d0d99c84070ae4cfd429760510cd 100644
--- a/src/main/jastadd/MinimalModel.relast
+++ b/src/main/jastadd/MinimalModel.relast
@@ -1,4 +1,36 @@
+Root ::= A* SenderRoot* ReceiverRoot* ;
+
 A ::= <Input:String> /<OutputOnA:String>/ B* C* /D/ Reading:D ;
 B ::= /<OutputOnB:String>/ ;
 C ::= /<OutputOnC:String>/ ;
 D ::= <ID:String> ;
+
+Nameable ::= <ID:int> ;
+SenderRoot : Nameable ::= <Input:int> /Alfa/ Bravo* Charlie* Delta* SenderSubTree ;
+SenderSubTree : Nameable ::= Hotel* ;
+
+ReceiverRoot : Nameable ::= Alfa Bravo* Charlie* Delta* ReceiverSubTree ;
+ReceiverSubTree : Nameable ::= Hotel* ;
+
+Alfa : Nameable ::= Echo* Foxtrot* Golf* ;
+
+Bravo : Nameable ;
+Charlie : Nameable ;
+Delta : Nameable ;
+Echo : Nameable ;
+Foxtrot : Nameable ;
+Golf : Nameable ;
+Hotel : Nameable ;
+
+rel Alfa.MyBravo -> Bravo ;
+rel Alfa.MultiBravo* -> Bravo ;
+// # relation into NTA not possible
+//rel Charlie.MyAlfa -> Alfa ;
+// # bidi relation from/into NTA probably not a good idea
+rel Alfa.MidiDelta <-> Delta.MidiAlfa? ;
+rel Alfa.MyEcho -> Echo ;
+rel Alfa.MultiEcho* -> Echo ;
+rel Foxtrot.MyAlfa? -> Alfa ;
+rel Alfa.MidiGolf <-> Golf.MidiAlfa? ;
+rel Alfa.MyHotel -> Hotel ;
+rel Alfa.MultiHotel* -> Hotel ;
diff --git a/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java b/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java
index 542ff536c5571c748dfd31e3ed012070a855a46f..d29074e58a857b2c0463eb1915a005239eaaffcc 100644
--- a/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java
+++ b/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java
@@ -9,6 +9,8 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.time.Instant;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 
@@ -17,6 +19,7 @@ import static java.util.concurrent.TimeUnit.SECONDS;
  *
  * @author rschoene - Initial contribution
  */
+@SuppressWarnings("CommentedOutCode")
 public class MinimalMain {
   private static final Logger logger = LogManager.getLogger(MinimalMain.class);
   private static final String TOPIC_FOR_INPUT = "topic/for/input";
@@ -52,7 +55,8 @@ public class MinimalMain {
     publisher.publish("---", ("Start at " + Instant.now()).getBytes());
 
 //    mainIncremental();
-    mainTree();
+//    mainSimpleTree();
+    mainRelationalTree();
   }
 
   private static void mainIncremental() throws Exception {
@@ -189,15 +193,18 @@ public class MinimalMain {
     logger.info("result.getD().getID() = " + result.getD().getID());
   }
 
-  private static void mainTree() throws IOException, InterruptedException {
+  private static void mainSimpleTree() throws IOException, InterruptedException {
     String uriString = "mqtt://localhost/normalA/d/out";
 
+    Root root = new Root();
+    root.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
+
     A sender = new A();
+    root.addA(sender);
     sender.setInput("123");
-    sender.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
 
     A receiver = new A();
-    receiver.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
+    root.addA(receiver);
     receiver.connectReading(uriString);
 
     sender.connectOutputOnA("mqtt://localhost/normalA/out", true);
@@ -215,6 +222,121 @@ public class MinimalMain {
     logger.info("receiver.getReading().getID() = " + receiver.getReading().getID());
   }
 
+  private static void mainRelationalTree() throws IOException, InterruptedException {
+    final String mqttUriString = "mqtt://localhost/alfa";
+
+    Root root1ForSender = new Root();
+    root1ForSender.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
+
+    SenderRoot senderRoot = createSenderRoot();
+    root1ForSender.addSenderRoot(senderRoot);
+    senderRoot.connectAlfa(mqttUriString, false);
+
+    Root root2ForReceiver = new Root();
+    root2ForReceiver.ragconnectSetupMqttWaitUntilReady(2, SECONDS);
+    ReceiverRoot receiverRoot = createReceiverRoot();
+    root2ForReceiver.addReceiverRoot(receiverRoot);
+    receiverRoot.connectAlfa(mqttUriString);
+    
+    senderRoot.setInput(1);
+    describedWait(1, "after setting input to 1");
+    printSender(senderRoot);
+    printReceiver(receiverRoot);
+
+    senderRoot.setInput(2);
+    describedWait(1, "after setting input to 2");
+    printSender(senderRoot);
+    printReceiver(receiverRoot);
+  }
+
+  private static void printSender(SenderRoot senderRoot) {
+    printAlfa("sender", senderRoot.getAlfa(), senderRoot::getDeltaList);
+  }
+
+  private static void printReceiver(ReceiverRoot receiverRoot) {
+    printAlfa("receiver", receiverRoot.getAlfa(), receiverRoot::getDeltaList);
+  }
+
+  private static SenderRoot createSenderRoot() {
+    SenderRoot result = new SenderRoot();
+    SenderSubTree subTree = new SenderSubTree();
+    result.setSenderSubTree(subTree);
+    templateCreation(result::addBravo, result::addCharlie, result::addDelta, subTree::addHotel);
+    return result;
+  }
+
+  private static ReceiverRoot createReceiverRoot() {
+    ReceiverRoot result = new ReceiverRoot();
+    ReceiverSubTree subTree = new ReceiverSubTree();
+    result.setReceiverSubTree(subTree);
+    templateCreation(result::addBravo, result::addCharlie, result::addDelta, subTree::addHotel);
+    return result;
+  }
+
+  private static void templateCreation(AddBravo addBravo, AddCharlie addCharlie, AddDelta addDelta, AddHotel addHotel) {
+    for (int i = 0; i < 4; i++) {
+      addBravo.accept(new Bravo(i));
+      addCharlie.accept(new Charlie(i));
+      addDelta.accept(new Delta(i));
+      addHotel.accept(new Hotel(i));
+    }
+  }
+
+  interface AddBravo { void accept(Bravo b); }
+  interface AddCharlie { void accept(Charlie b); }
+  interface AddDelta { void accept(Delta b); }
+  interface GetDeltaList { Iterable<Delta> get(); }
+  interface AddHotel { void accept(Hotel b); }
+
+  private static void printAlfa(String name, Alfa alfa, GetDeltaList getDeltaList) {
+    StringBuilder sbDelta = new StringBuilder();
+    for (Delta delta : getDeltaList.get()) {
+      sbDelta.append(delta.getID())
+          .append("->")
+          .append(delta.hasMidiAlfa() ? delta.getMidiAlfa().getID() : "/")
+          .append(", ");
+    }
+    String deltaList = sbDelta.toString();
+    StringBuilder sbFoxtrot = new StringBuilder();
+    for (Foxtrot foxtrot : alfa.getFoxtrotList()) {
+      sbFoxtrot.append(foxtrot.getID())
+          .append("->")
+          .append(foxtrot.hasMyAlfa() ? foxtrot.getMyAlfa().getID() : "/")
+          .append(", ");
+    }
+    String foxtrotList = sbFoxtrot.toString();
+    logger.info("Checking Alfa\n" +
+        "{}: {} in {}\n" +
+        " |- MyBravo: {}\n" +
+        " |- MultiBravoList: {}\n" +
+        " |- MidiDelta: {} (MidiDelta.getMidiAlfa(): {})\n" +
+        " |- DeltaList: {}\n" +
+        " |- MyEcho: {}\n" +
+        " |- MultiEchoList: {}\n" +
+        " |- FoxtrotList (id -> alfa.id): {}\n" +
+        " |- MidiGolf: {} (MidiGolf.getMidiAlfa(): {})\n" +
+        " |- MyHotel: {}\n" +
+        " |- MultiHotelList: {}" +
+        "{}", // just to make swapping of params easier (all have a comma at the end)
+        name, alfa, alfa.getParent(),
+        alfa.getMyBravo().getID(),
+        printNameableList(alfa.getMultiBravoList()),
+        alfa.getMidiDelta().getID(), alfa.getMidiDelta().getMidiAlfa(),
+        deltaList,
+        alfa.getMyEcho().getID(),
+        printNameableList(alfa.getMultiEchoList()),
+        foxtrotList,
+        alfa.getMidiGolf().getID(), alfa.getMidiGolf().getMidiAlfa(),
+        alfa.getMyHotel().getID(),
+        printNameableList(alfa.getMultiHotelList()),
+        ""
+    );
+  }
+  
+  private static String printNameableList(List<? extends Nameable> nameableList) {
+    return nameableList.stream().map(nameable -> Integer.toString(nameable.getID())).collect(Collectors.joining(",", "[", "]"));
+  }
+
 
 //  private static void enableTracing(ASTNode<?> node) {
 //    if (node.trace().getReceiver() != null && node.trace().getReceiver() instanceof MinimalReceiver) {