diff --git a/build.gradle b/build.gradle
index d893e1b17132278a8c1da641ed97cfb7e4511b16..126c0146b98bae482f49047cba4508c666ae1f18 100644
--- a/build.gradle
+++ b/build.gradle
@@ -89,7 +89,7 @@ def loadingRelastFiles = ['./src/main/jastadd/common/MotionGrammar.relast', './s
 def cleaningRelastFiles = ['./src/main/jastadd/common/MotionGrammar.relast', './src/main/jastadd/cleanup/RobotWorld.relast', './src/main/jastadd/cleanup/Cleanup.relast']
 def grammarPrefix = './src/gen/jastadd/MotionGrammar'
 def loadingGrammarDiagramFile = './src/gen/resources/diagrams/grammar/loading.png'
-def cleaningGrammarDiagramFile = './src/gen/resources/diagrams/grammar/cleaning.png'
+def cleaningGrammarDiagramFile = './src/gen/resources/diagrams/grammar/cleaning.puml'
 def jastAddListName = 'JastAddList'
 
 task generateLoadingGrammarDiagrams(type: JavaExec) {
@@ -107,7 +107,7 @@ task generateCleaningGrammarDiagrams(type: JavaExec) {
     group = 'Documentation'
     classpath = configurations.grammar2uml
 
-    args "--output=${cleaningGrammarDiagramFile}", '--defaultFolders'
+    args "--output=${cleaningGrammarDiagramFile}", '--defaultFolders', '--printSource'
     args cleaningRelastFiles
 
     inputs.files cleaningRelastFiles
diff --git a/gradle.properties b/gradle.properties
index 4f0ee66dd8bd5c1e752d4d9e1e0b6889e087c15e..08db7214a1bd07bb1e3c104d563211783404e6f6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
 relast_version = 0.3.0-137
-relast2uml_version = 1.0.0
+relast2uml_version = 1.0.2-68
 jupyter_version = 5.8.2
 assertj_version = 3.22.0
 grammar2uml_version = 0.2.1
diff --git a/material/2022-05-31-research-discussion.odp b/material/2022-05-31-research-discussion.odp
index d02f6f8c376adc42b302a736ea19017932c5b493..b994241547651755158e533c4400f49d31247cb2 100644
Binary files a/material/2022-05-31-research-discussion.odp and b/material/2022-05-31-research-discussion.odp differ
diff --git a/material/overview.drawio b/material/overview.drawio
index ca260e737ff4c34b6b2357b58dd8ee029fca997e..3dd4ab3ff9738e76a29c83aac23d46f786ca49e5 100644
--- a/material/overview.drawio
+++ b/material/overview.drawio
@@ -1 +1 @@
-<mxfile host="Electron" modified="2022-05-30T15:22:45.891Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/18.1.3 Chrome/100.0.4896.143 Electron/18.2.3 Safari/537.36" etag="In4-8qNJInGg5Ttx52PO" version="18.1.3" type="device"><diagram id="xllGRi-CdCWfJc1u12WW" name="Page-1">7Vpdb6M4FP01fSzyF8Z+bDvT3dmdSiN1pdE+VQ44gBZwFpxJZn79XggQwHTazoZ2qk6ktsm1+eg591yfa3JGr/L9b6XaJDcm0tkZQdH+jL47I0QKDL/rwNdDwBf8EIjLNDqE8DFwm37TbRC10W0a6Wo00RqT2XQzDoamKHRoRzFVlmY3nrY22fiqGxVrJ3AbqqyNkmP0cxrZpJ2LEToO/K7TOGkvLfx2IFfd5DZQJSoyu0GIvj+jV6Ux9vAu31/prMauw+Vw3PU9o/3tlrqwjzngm/n75g8/+ZNEHxVOgg/nH9TqnASH03xR2bb9j9u7tV87CEqzLSJdnwWd0ctdklp9u1FhPboDziGW2DyDTxjerk1hWxYxh8/t6XVp9f7eG8c9HJBG2uTall9hSnuAaAFsM4h00O+OfAQdyMmACtZNVG0OxP2pjzDBmxapJ6BGHdAudaK+pGZbfgc9/DB6NU4pJN9FlsYFxKzZjDElNQXrNMuuTGbK5go0UlqsQ4hXtjT/6MEID4VerU/Dgs8mNDCXhj42pIGSpWjADg1XgJTe25cgwdciYnMkCLKi/ERSwJI+TMKcFpYjwb+fhOvPpoRyS3gGd3G5Kkec8H+3deVrcD2vGmAvYALmm32DVTcO7+L6Lywvea5cfXVsfVQrnX0yVWpTU7O2Mtaa/F46B3xDYd7UJ8v3cb2EeStVpaGnwq3Vd7ZMVRHX17psljTk+TNFbpILCAmF0FwuIOQHzUh9hi4e6bXaZvY0GULwOEMo8T2OnSTBdCZJcMA8KhfKE+7kyY1pqHqD6eEjvZ5PD/zu8mrJ9ODcH6UHo24B6b3NMDeCpeqHfNiAdAxUaY31Re3qnm5EGjPYWTjksS7UzkEeYqeBmMoxxEQ+skYvt066C2WnPdTr5qjCg6A+qbLSrp6ayj7WxyiLC1PoScq3IdUKLAQc4cSu8vI0ihopzTE7NqELuMwAHQtlx1zgMsdnjeZSxJEfFUeUltANHUpdZbb13f9PwUDpGL8cARE8nhA0tFnV3sY59U9Uw4TDFPVnV7k5lS1WyDA7BVk7Xdklihv03QRxIbnv44AwPOGmsbSnsB+B9MiEG0k9LhxuKKNeIJ+zCrqt7l9QuIrq7dQ4hviDBQ77c+3DYqQIh5RbnasCQIPoRaOK10LQEnpiaGLnpXxpxlzDFgJHttyGtqpP7TgJtdnoInotLC5jJSh/nJVYjDbiesDqKLS0WJsyP2TvHIV9pOfUQuuzghao6obguNVx+luhmqOH+6nn5fkRljHNm03vIR1t6F2ax3DZLAUqr8Ms3dypst7ICU2+AbLLWuC3Zm13ANAdJmIPP96miJcBl5JJJyVmwBUzFo94/lLwulu/jYn41T+RgD5M1nM2T8T1478q3glE2fnofmVjHnFNyfMWPXcT2iHk9fTJmJ2oUSaTpwV0ZnF61ha5u/7PwBNjtXMWPhOAC/HllKbp5kXdU0eqSvqnSKdwD1R6YkwRlh72HZYw3G/gEiUWW+Z+IqJOICh5qp2nAHl4QlggPUoeJSuMF6t/bhf9YnRRJjlH3Bfc92UgHF15CMoSQwQLhJnEPsV0TJdECyiNSWjJJgYFCw+7zOGgj462pcDokqXkRt3mzOHv6aY91oUuFVz8+j0Ekrs4M6upax/h7Dy3Wuop1PQbHbI37AMixIyExGIrk+vr71VQZLarH34MNY/pIP2bxX+qKSpASoJDFiMWSOaWQAzFJYBiFDDBuGTiRAUPE9mbu34HCs/5PVhKPT6nm8CTeCnSXIcPrluXRZ30U0Ov12t93w5VmKgi1m9oh2oiQCqlJ4cvNsPvs24yPsJ/vJZdDI4n1S7A/YOPAcDdU+MhvlL0D1OeADF8PH6rsBkbfDWTvv8P</diagram></mxfile>
\ No newline at end of file
+<mxfile host="Electron" modified="2022-06-10T07:40:44.173Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/18.1.3 Chrome/100.0.4896.143 Electron/18.2.3 Safari/537.36" etag="r6BY6nRAQaejeYnjVoee" version="18.1.3" type="device"><diagram id="xllGRi-CdCWfJc1u12WW" name="Page-1">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</diagram></mxfile>
\ No newline at end of file
diff --git a/material/overview.drawio-full.png b/material/overview.drawio-full.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1f9b10fa0ff88f130c1040a884227da0ce93c5c
Binary files /dev/null and b/material/overview.drawio-full.png differ
diff --git a/material/overview.drawio.png b/material/overview.drawio.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1827b8dc9f04c7804d469134989a5352016096a
Binary files /dev/null and b/material/overview.drawio.png differ
diff --git a/src/main/jastadd/cleanup/Cleanup.relast b/src/main/jastadd/cleanup/Cleanup.relast
index b37e9352bbd28a44ab6059a2566ce0c83ecdc278..f6b4d3338eca4b20614d621dd83248da82c6145e 100644
--- a/src/main/jastadd/cleanup/Cleanup.relast
+++ b/src/main/jastadd/cleanup/Cleanup.relast
@@ -2,8 +2,11 @@ Tidy : MotionGrammarElement ::= MoveObjectToCorrectPlace* WaitForEmptyTable* Emp
 MoveObjectToCorrectPlace : MotionGrammarElement ::= ObjectAtWrongPlace/*provides object*/ PickUpObject/*uses object*/ DropObjectAtRightPlace/*uses object*/;
 PickUpObject/*requires object*/ : MotionGrammarElement ::= RobotIsReadyToPick Pick/*uses object*/;
 abstract RobotIsReadyToPick : MotionGrammarElement;
-RobotIsReallyReadyToPick : RobotIsReadyToPick ::= RobotIsFree;
-RobotIsNotReadyToPick    : RobotIsReadyToPick ::= RobotIsBusy Wait/*uses const "1sec"*/ RobotIsReadyToPick;
+RobotIsReallyReadyToPick : RobotIsReadyToPick ::= RobotIsReadyToPickToken;
+RobotIsNotReadyToPick    : RobotIsReadyToPick ::= RobotIsNotReadyToPickToken Wait/*uses const "1sec"*/ RobotIsReadyToPick;
+abstract RobotIsReadyToDrop : MotionGrammarElement;
+RobotIsReallyReadyToDrop : RobotIsReadyToDrop ::= RobotIsReadyToDropToken;
+RobotIsNotReadyToDrop    : RobotIsReadyToDrop ::= RobotIsNotReadyToDropToken Wait/*uses const "1sec"*/ RobotIsReadyToPick;
 DropObjectAtRightPlace/*requires object*/ : MotionGrammarElement ::= RightPlace/*uses object, provides place*/ Drop/*uses place*/;
 WaitForEmptyTable : MotionGrammarElement ::= NotEmptyTable Wait/*uses const "1sec"*/;
 
@@ -12,10 +15,14 @@ EmptyTable                        : Token;
 NotEmptyTable                     : Token; // TODO should be improved to express EmptyTable can not be parsed
 ObjectAtWrongPlace                : Token ::= <Object:String>; // the Object is a variable of the token
 Pick/*requires object*/           : Token;
-RobotIsFree                       : Token ::= RobotIsIdle RobotHasNoItemAttached; // combined token. both individual tokens are parsed in parallel
-RobotIsBusy                       : Token; // TODO should be improved to express RobotIsFree can not be parsed
+RobotIsReadyToPickToken           : Token ::= RobotIsIdle RobotHasNoItemAttached; // combined token. both individual tokens are parsed in parallel
+RobotIsNotReadyToPickToken        : Token ::= [RobotIsNotIdle] /*or*/ [RobotHasItemAttached]; // TODO negated RobotIsReadyToPickToken
+RobotIsReadyToDropToken           : Token ::= RobotIsIdle RobotHasItemAttached;   // combined token. both individual tokens are parsed in parallel
+RobotIsNotReadyToDropToken        : Token ::= [RobotIsNotIdle] /*or*/ [RobotHasNoItemAttached]; // TODO negated RobotIsReadyToDropToken
 RobotIsIdle                       : Token;
-RobotHasNoItemAttached            : Token;
+RobotIsNotIdle                    : Token; // TODO negated RobotIsIdle
+RobotHasItemAttached              : Token;
+RobotHasNoItemAttached            : Token; // TODO negated RobotHasItemAttached
 Wait/*requires time*/             : Token; // artificial token, which parsing takes a specified amount of time
 RightPlace/*requires object*/     : Token ::= <Place:String>;
 Drop/*requires object and place*/ : Token;
diff --git a/src/main/jastadd/cleanup/RobotWorld.jadd b/src/main/jastadd/cleanup/RobotWorld.jadd
index a3a565901afdb1d2baf3c13636fccc9986be82c9..e8d8619bce2f69e479027e9fd90f627b6446c1b5 100644
--- a/src/main/jastadd/cleanup/RobotWorld.jadd
+++ b/src/main/jastadd/cleanup/RobotWorld.jadd
@@ -11,16 +11,21 @@ aspect RobotWorld {
     return new RobotScene(t, b);
   }
 
-  public static TokenType EmptyTable.type()             { return TokenType.of("EMPTY_TABLE"); }
-  public static TokenType ObjectAtWrongPlace.type()     { return TokenType.of("OBJECT_AT_WRONG_PLACE"); }
-  public static TokenType Pick.type()                   { return TokenType.of("PICK"); }
-  public static TokenType RobotIsFree.type()            { return TokenType.of("ROBOT_IS_FREE"); }
-  public static TokenType RobotIsBusy.type()            { return TokenType.of("ROBOT_IS_BUSY"); }
-  public static TokenType RobotIsIdle.type()            { return TokenType.of("ROBOT_IS_IDLE"); }
-  public static TokenType RobotHasNoItemAttached.type() { return TokenType.of("ROBOT_HAS_NO_ITEM_ATTACHED"); }
-  public static TokenType Wait.type()                   { return TokenType.of("WAIT"); }
-  public static TokenType RightPlace.type()             { return TokenType.of("RIGHT_PLACE"); }
-  public static TokenType Drop.type()                   { return TokenType.of("DROP"); }
+  public static TokenType EmptyTable.type()                 { return TokenType.of("EMPTY_TABLE"); }
+  public static TokenType NotEmptyTable.type()              { return TokenType.of("NOT_EMPTY_TABLE"); }
+  public static TokenType ObjectAtWrongPlace.type()         { return TokenType.of("OBJECT_AT_WRONG_PLACE"); }
+  public static TokenType Pick.type()                       { return TokenType.of("PICK"); }
+  public static TokenType RobotIsReadyToPickToken.type()    { return TokenType.of("ROBOT_IS_READY_TO_PICK_TOKEN"); }
+  public static TokenType RobotIsNotReadyToPickToken.type() { return TokenType.of("ROBOT_IS_NOT_READY_TO_PICK_TOKEN"); }
+  public static TokenType RobotIsReadyToDropToken.type()    { return TokenType.of("ROBOT_IS_READY_TO_DROP_TOKEN"); }
+  public static TokenType RobotIsNotReadyToDropToken.type() { return TokenType.of("ROBOT_IS_NOT_READY_TO_DROP_TOKEN"); }
+  public static TokenType RobotIsIdle.type()                { return TokenType.of("ROBOT_IS_IDLE"); }
+  public static TokenType RobotIsNotIdle.type()             { return TokenType.of("ROBOT_IS_NOT_IDLE"); }
+  public static TokenType RobotHasItemAttached.type()       { return TokenType.of("ROBOT_HAS_ITEM_ATTACHED"); }
+  public static TokenType RobotHasNoItemAttached.type()     { return TokenType.of("ROBOT_HAS_NO_ITEM_ATTACHED"); }
+  public static TokenType Wait.type()                       { return TokenType.of("WAIT"); }
+  public static TokenType RightPlace.type()                 { return TokenType.of("RIGHT_PLACE"); }
+  public static TokenType Drop.type()                       { return TokenType.of("DROP"); }
 
   public static Pose Pose.of(double x, double y, double z) {
     return new Pose(x, y, z, 0, 0, 0, 1);
@@ -95,32 +100,66 @@ aspect RobotWorld {
     }
   }
 
-  public RobotIsFree World.parseRobotIsFree() {
+  public RobotIsReadyToPickToken World.parseRobotIsReadyToPickToken() {
     return null;
   }
-  public RobotIsFree RobotScene.parseRobotIsFree() {
-    System.out.println("Trying to parse token <RobotIsFree> by parsing sub-tokens...");
+  public RobotIsReadyToPickToken RobotScene.parseRobotIsReadyToPickToken() {
+    System.out.println("Trying to parse token <RobotIsReadyToPickToken> by parsing ALL sub-tokens...");
     RobotIsIdle idle = parseRobotIsIdle();
     RobotHasNoItemAttached noItem = parseRobotHasNoItemAttached();
     if (idle != null && noItem != null) {
-      System.out.println("Trying to parse token <RobotIsFree> by parsing sub-tokens... success");
-      return new RobotIsFree(idle, noItem);
+      System.out.println("Trying to parse token <RobotIsReadyToPickToken> by parsing ALL sub-tokens... success");
+      return new RobotIsReadyToPickToken(idle, noItem);
     } else {
-      System.out.println("Trying to parse token <RobotIsFree> by parsing sub-tokens... failure");
+      System.out.println("Trying to parse token <RobotIsReadyToPickToken> by parsing ALL sub-tokens... failure");
       return null;
     }
   }
 
-  public RobotIsBusy World.parseRobotIsBusy(){
+  public RobotIsNotReadyToPickToken World.parseRobotIsNotReadyToPickToken() {
     return null;
   }
-  public RobotIsBusy RobotScene.parseRobotIsBusy(){
-    System.out.print("Trying to parse token <RobotIsBusy>... ");
-    if (!getRobot().getIsIdle()) {
-      System.out.println("success");
-      return new RobotIsBusy();
+  public RobotIsNotReadyToPickToken RobotScene.parseRobotIsNotReadyToPickToken() {
+    System.out.println("Trying to parse token <RobotIsNotReadyToPickToken> by parsing ANY sub-tokens...");
+    RobotIsNotIdle notIdle = parseRobotIsNotIdle();
+    RobotHasItemAttached item = parseRobotHasItemAttached();
+    if (notIdle != null || item != null) {
+      System.out.println("Trying to parse token <RobotIsNotReadyToPickToken> by parsing ANY sub-tokens... success");
+      return new RobotIsNotReadyToPickToken(new Opt<>(notIdle), new Opt<>(item));
     } else {
-      System.out.println("failure");
+      System.out.println("Trying to parse token <RobotIsNotReadyToPickToken> by parsing ANY sub-tokens... failure");
+      return null;
+    }
+  }
+
+  public RobotIsReadyToDropToken World.parseRobotIsReadyToDropToken() {
+    return null;
+  }
+  public RobotIsReadyToDropToken RobotScene.parseRobotIsReadyToDropToken() {
+    System.out.println("Trying to parse token <RobotIsReadyToDropToken> by parsing ALL sub-tokens...");
+    RobotIsIdle idle = parseRobotIsIdle();
+    RobotHasItemAttached item = parseRobotHasItemAttached();
+    if (idle != null && item != null) {
+      System.out.println("Trying to parse token <RobotIsReadyToDropToken> by parsing ALL sub-tokens... success");
+      return new RobotIsReadyToDropToken(idle, item);
+    } else {
+      System.out.println("Trying to parse token <RobotIsReadyToDropToken> by parsing ALL sub-tokens... failure");
+      return null;
+    }
+  }
+
+  public RobotIsNotReadyToDropToken World.parseRobotIsNotReadyToDropToken() {
+    return null;
+  }
+  public RobotIsNotReadyToDropToken RobotScene.parseRobotIsNotReadyToDropToken() {
+    System.out.println("Trying to parse token <RobotIsNotReadyToDropToken> by parsing ANY sub-tokens...");
+    RobotIsNotIdle notIdle = parseRobotIsNotIdle();
+    RobotHasNoItemAttached noItem = parseRobotHasNoItemAttached();
+    if (notIdle != null || noItem != null) {
+      System.out.println("Trying to parse token <RobotIsNotReadyToDropToken> by parsing ANY sub-tokens... success");
+      return new RobotIsNotReadyToDropToken(new Opt<>(notIdle), new Opt<>(noItem));
+    } else {
+      System.out.println("Trying to parse token <RobotIsNotReadyToDropToken> by parsing ANY sub-tokens... failure");
       return null;
     }
   }
@@ -139,6 +178,34 @@ aspect RobotWorld {
     }
   }
 
+  public RobotIsNotIdle World.parseRobotIsNotIdle() {
+    return null;
+  }
+  public RobotIsNotIdle RobotScene.parseRobotIsNotIdle() {
+    System.out.print("Trying to parse token <RobotIsNotIdle>... ");
+    if (!getRobot().getIsIdle()) {
+      System.out.println("success");
+      return new RobotIsNotIdle();
+    } else {
+      System.out.println("failure");
+      return null;
+    }
+  }
+
+  public RobotHasItemAttached World.parseRobotHasItemAttached() {
+    return null;
+  }
+  public RobotHasItemAttached RobotScene.parseRobotHasItemAttached() {
+    System.out.print("Trying to parse token <RobotHasItemAttached>... ");
+    if (getRobot().hasAttachedItem()) {
+      System.out.println("success");
+      return new RobotHasItemAttached();
+    } else {
+      System.out.println("failure");
+      return null;
+    }
+  }
+
   public RobotHasNoItemAttached World.parseRobotHasNoItemAttached() {
     return null;
   }
diff --git a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
index 8a0dd1f881381579f799166f0e489ad55b43836f..9027b34c81ddeaae2df2d3091b4f7f02d9a1853e 100644
--- a/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
+++ b/src/main/java/de/tudresden/inf/st/mg/RobotParser.java
@@ -20,9 +20,13 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
   private NotEmptyTable peekedNotEmptyTable_ = null;
   private ObjectAtWrongPlace peekedObjectAtWrongPlace_ = null;
   private Pick peekedPick_ = null;
-  private RobotIsFree peekedRobotIsFree_ = null;
-  private RobotIsBusy peekedRobotIsBusy_ = null;
+  private RobotIsReadyToPickToken peekedRobotIsReadyToPickToken_ = null;
+  private RobotIsNotReadyToPickToken peekedRobotIsNotReadyToPickToken_ = null;
+  private RobotIsReadyToDropToken peekedRobotIsReadyToDropToken_ = null;
+  private RobotIsNotReadyToDropToken peekedRobotIsNotReadyToDropToken_ = null;
   private RobotIsIdle peekedRobotIsIdle_ = null;
+  private RobotIsNotIdle peekedRobotIsNotIdle_ = null;
+  private RobotHasItemAttached peekedRobotHasItemAttached_ = null;
   private RobotHasNoItemAttached peekedRobotHasNoItemAttached_ = null;
   private Wait peekedWait_ = null;
   private RightPlace peekedRightPlace_ = null;
@@ -174,17 +178,17 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
   private void parseRobotIsReadyToPick(ASTNode<?> parent, int index) throws ParseException {
     RobotIsReadyToPick result;
 
-    // try to parse a T
-    if (peekRobotIsFree()) {
+    // try to parse a RobotIsReadyToPickToken
+    if (peekRobotIsReadyToPickToken()) {
       result = new RobotIsReallyReadyToPick();
       parent.setChild(result, index);
       parseRobotIsReallyReadyToPick(parent, index);
-    } else if (peekRobotIsBusy()) {
+    } else if (peekRobotIsNotReadyToPickToken()) {
       result = new RobotIsNotReadyToPick();
       parent.setChild(result, index);
       parseRobotIsNotReadyToPick(parent, index);
     } else {
-      throw new ParseException("RobotIsReadyToPick", RobotIsFree.type(), RobotIsBusy.type());
+      throw new ParseException("RobotIsReadyToPick", RobotIsReadyToPickToken.type(), RobotIsNotIdle.type());
     }
 
     // semantic action for T1
@@ -195,42 +199,42 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
   private void parseRobotIsReallyReadyToPick(ASTNode<?> parent, int index) throws ParseException {
     RobotIsReallyReadyToPick result = (RobotIsReallyReadyToPick) parent.getChild(index);
 
-    parseRobotIsFree(result, 0);
+    parseRobotIsReadyToPickToken(result, 0);
 
     // semantic action for T1
     result.action(getWorld());
     printAST("parseRobotIsReallyReadyToPick", result);
   }
 
-  private boolean peekRobotIsFree() {
-    peekedRobotIsFree_ = getWorld().parseRobotIsFree();
-    return peekedRobotIsFree_ != null;
+  private boolean peekRobotIsReadyToPickToken() {
+    peekedRobotIsReadyToPickToken_ = getWorld().parseRobotIsReadyToPickToken();
+    return peekedRobotIsReadyToPickToken_ != null;
   }
 
-  private void parseRobotIsFree(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsFree result;
+  private void parseRobotIsReadyToPickToken(ASTNode<?> parent, int index) throws ParseException {
+    RobotIsReadyToPickToken result;
 
-    if (peekedRobotIsFree_ != null) {
-      result = peekedRobotIsFree_;
-      peekedRobotIsFree_ = null; // TODO check if all peeked values are actually parsed afterwards
+    if (peekedRobotIsReadyToPickToken_ != null) {
+      result = peekedRobotIsReadyToPickToken_;
+      peekedRobotIsReadyToPickToken_ = null; // TODO check if all peeked values are actually parsed afterwards
     } else {
-      result = getWorld().parseRobotIsFree();
+      result = getWorld().parseRobotIsReadyToPickToken();
       if (result == null) {
-        throw new ParseException(RobotIsFree.type());
+        throw new ParseException(RobotIsReadyToPickToken.type());
       }
     }
 
     parent.setChild(result, index);
 
-    // semantic action for RobotIsFree
+    // semantic action for RobotIsReadyToPickToken
     result.action(getWorld());
-    printAST("parseRobotIsFree", result);
+    printAST("parseRobotIsReadyToPickToken", result);
   }
 
   private void parseRobotIsNotReadyToPick(ASTNode<?> parent, int index) throws ParseException {
     RobotIsNotReadyToPick result = (RobotIsNotReadyToPick) parent.getChild(index);
 
-    parseRobotIsBusy(result, 0);
+    parseRobotIsNotIdle(result, 0);
     parseWait(result, 1);
     parseRobotIsReadyToPick(result, 2);
 
@@ -239,29 +243,29 @@ public final class RobotParser extends MotionGrammarParser<Tidy> {
     printAST("parseRobotIsNotReadyToPick", result);
   }
 
-  private boolean peekRobotIsBusy() {
-    peekedRobotIsBusy_ = getWorld().parseRobotIsBusy();
-    return peekedRobotIsBusy_ != null;
+  private boolean peekRobotIsNotIdle() {
+    peekedRobotIsNotIdle_ = getWorld().parseRobotIsNotIdle();
+    return peekedRobotIsNotIdle_ != null;
   }
 
-  private void parseRobotIsBusy(ASTNode<?> parent, int index) throws ParseException {
-    RobotIsBusy result;
+  private void parseRobotIsNotIdle(ASTNode<?> parent, int index) throws ParseException {
+    RobotIsNotIdle result;
 
-    if (peekedRobotIsBusy_ != null) {
-      result = peekedRobotIsBusy_;
-      peekedRobotIsBusy_ = null; // TODO check if all peeked values are actually parsed afterwards
+    if (peekedRobotIsNotIdle_ != null) {
+      result = peekedRobotIsNotIdle_;
+      peekedRobotIsNotIdle_ = null; // TODO check if all peeked values are actually parsed afterwards
     } else {
-      result = getWorld().parseRobotIsBusy();
+      result = getWorld().parseRobotIsNotIdle();
       if (result == null) {
-        throw new ParseException(RobotIsBusy.type());
+        throw new ParseException(RobotIsNotIdle.type());
       }
     }
 
     parent.setChild(result, index);
 
-    // semantic action for RobotIsBusy
+    // semantic action for RobotIsNotIdle
     result.action(getWorld());
-    printAST("parseRobotIsBusy", result);
+    printAST("parseRobotIsNotIdle", result);
   }
 
   private void parseWait(ASTNode<?> parent, int index) throws ParseException {
diff --git a/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java b/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java
index 1beccfbc48e57fddb99903cb5edff43747e581a3..706c7a980464f168bcda52ac87594123c6caa7b2 100644
--- a/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java
+++ b/src/main/java/de/tudresden/inf/st/mg/common/MotionGrammarParser.java
@@ -2,6 +2,7 @@ package de.tudresden.inf.st.mg.common;
 
 import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
 import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamBooleanSetting;
+import de.tudresden.inf.st.jastadd.dumpAst.ast.SkinParamStringSetting;
 import de.tudresden.inf.st.mg.jastadd.model.*;
 
 import java.io.IOException;
@@ -42,8 +43,10 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
     try {
 
       for (var contextEntry : contexts_.entrySet()) {
+//        System.out.println("REL: " + ((RobotScene) (contextEntry.getValue())).getRobot().getAttachedItem());
         Dumper.read(contextEntry.getValue())
                 .setNameMethod(o -> o == null ? "null" : o.getClass().getSimpleName())
+                .includeRelationsFor(".*", ".*")
                 .dumpAsPNG(astDiagramDir_.resolve("Context-" + contextEntry.getKey() + "-" + String.format("%03d", timeStep_) + "-" + step + ".png"));
       }
       // TODO remove this once the issue in relast2uml has been resolved
@@ -60,7 +63,9 @@ public abstract class MotionGrammarParser<T extends MotionGrammarElement> {
                   return result + o.getClass().getSimpleName();
                 })
                 .skinParam(SkinParamBooleanSetting.Shadowing, false)
+                .skinParam(SkinParamStringSetting.backgroundColor, "white")
 //                .dumpAsSource(astDiagramDir_.resolve("AST-" + String.format("%03d", timeStep_) + "-" + step + ".puml"))
+//                .dumpAsSVG(astDiagramDir_.resolve("AST-" + String.format("%03d", timeStep_) + "-" + step + ".svg"));
                 .dumpAsPNG(astDiagramDir_.resolve("AST-" + String.format("%03d", timeStep_) + "-" + step + ".png"));
       }
       timeStep_++;
diff --git a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java
index c4dbd33b40727f5089745ac10b6c9200472cdfb5..b88ce99baeda404224b2f9a5f54864aa3281d57e 100644
--- a/src/test/java/de/tudresden/inf/st/mg/ParserTest.java
+++ b/src/test/java/de/tudresden/inf/st/mg/ParserTest.java
@@ -52,15 +52,17 @@ public class ParserTest {
   @Test
   void runTidyParser() throws MotionGrammarParser.ParseException {
 
-    // for some reason, the best random seed value here is 1 and not 0???
-    World world = RobotScene.initialWorld(new Random(1));
+// for some reason, the best random seed value here is 1 and not 0???
+World world = RobotScene.initialWorld(new Random(1));
 
-    RobotParser parser = new RobotParser(world);
-    parser.setDebugDiagramDir(TIDY_AST_DIAGRAM_DIR);
+// create a parser using the world
+RobotParser parser = new RobotParser(world);
+parser.setDebugDiagramDir(TIDY_AST_DIAGRAM_DIR);
 
-    var result = parser.parse();
+// parse (synchonously, long-running)
+var result = parser.parse();
 
-    assertThat(result).isNotNull().isInstanceOf(Tidy.class);
+assertThat(result).isNotNull().isInstanceOf(Tidy.class);
   }
 
 }