diff --git a/build.gradle b/build.gradle
index f1f3b408f121f388615eca5d85cd3f128128f17c..6cc84133b33e0335daf810d71955697360cfd8d3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -37,10 +37,10 @@ subprojects {
 	}
 
 	dependencies {
-		compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.2'
-		compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.2'
-		testCompile group: 'junit', name: 'junit', version: '4.12'
-		testCompile group: 'org.hamcrest', name: 'hamcrest-junit', version: '2.0.0.0'
+		implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.2'
+		implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.2'
+		testImplementation group: 'junit', name: 'junit', version: '4.12'
+		testImplementation group: 'org.hamcrest', name: 'hamcrest-junit', version: '2.0.0.0'
 	}
 
 }
diff --git a/statemachine/DrAST.cfg b/statemachine/DrAST.cfg
index c229f19b6e4a7ae45494a802615a084bd488a49c..a5e75e925199099f743ed7cea31321a0f60d70d4 100644
--- a/statemachine/DrAST.cfg
+++ b/statemachine/DrAST.cfg
@@ -1,4 +1,16 @@
+#DrAST settings file.
+#Mon Nov 18 17:23:41 CET 2019
+normalEdgeWidth=1.0
+showEdges=true
+refEdgeWidth=2.0
+NTA-depth=1
+NTA-cached=1
 dynamic-values=0
+prevJar=build/libs/statemachine-0.1.jar
+dashedVertexEdgeWidth=0.2
 NTA-computed=0
-NTA-cached=1
-NTA-depth=1
+normalVertexEdgeWidth=1.0
+nodeThreshold=1000
+showNodes=true
+curvedEdges=true
+dashedEdgeWidth=0.2
diff --git a/statemachine/build.gradle b/statemachine/build.gradle
index 35c8c24b902857777be1f34f0a3b8306352a5291..022baba06ecc05ab5fb30f0896959dda4e67b8b8 100644
--- a/statemachine/build.gradle
+++ b/statemachine/build.gradle
@@ -1,23 +1,46 @@
+group 'de.tudresden.inf.st'
+version '2.0-SNAPSHOT'
+
+apply plugin: 'java'
 apply plugin: 'jastadd'
 apply plugin: 'application'
-apply plugin: 'jacoco'
-apply plugin: 'idea'
-apply plugin: 'distribution'
+apply plugin: "idea"
+
+sourceCompatibility = 1.8
+
+repositories {
+    mavenCentral()
+}
+
+idea {
+    module {
+        generatedSourceDirs += file('src/gen/java')
+    }
+}
+
+configurations {
+    ragdoc
+}
+
+sourceSets {
+    main {
+        java.srcDir "src/gen/java"
+    }
+}
+
+task cleanRagdoc(type: Delete) {
+    group = 'documentation'
+    new File(docsDir, 'ragdoc').deleteDir()
+}
 
 dependencies {
     implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jackson_version}"
     implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
-    jastadd2 "org.jastadd:jastadd:2.3.4"
-//    ragdoc project(":ragdoc-builder")
     implementation files('../libs/DrAST-1.2.2.jar')
-}
+    implementation fileTree(dir: "${System.properties['java.home']}", include: '**/jfxrt.jar')
 
-buildscript {
-    repositories.mavenLocal()
-    repositories.mavenCentral()
-    dependencies {
-        classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
-    }
+    jastadd2 "org.jastadd:jastadd:2.3.4"
+    ragdoc files('../libs/rd-builder.jar')
 }
 
 run {
@@ -28,10 +51,20 @@ run {
     }
 }
 
-test {
-    testLogging {
-        events "passed", "skipped", "failed"
-        exceptionFormat "full"
+buildscript {
+    repositories.mavenLocal()
+    repositories.mavenCentral()
+    dependencies {
+        classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
+    }
+}
+
+jar {
+    manifest {
+        attributes(
+                'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
+                'Main-Class': 'de.tudresden.inf.st.statemachine.Main'
+        )
     }
 }
 
@@ -39,7 +72,7 @@ task DrAST(type: JavaExec, dependsOn:jar) {
     group = "verification"
     description = 'run the DrAST visual debugger tool'
     classpath = sourceSets.test.runtimeClasspath
-    main = 'de.tudresden.inf.st.statemachine.Main'
+    main = 'de.tudresden.inf.st.statemachine.DrAstRunner'
 }
 
 String[] drastArguments = ['../libs/DrAST-1.2.2.jar']
@@ -50,26 +83,26 @@ task DrASTjar(type: JavaExec, dependsOn:jar) {
     args drastArguments
 }
 
-jacocoTestReport {
-    reports {
-        xml.enabled true
-        html.enabled false
-    }
-}
-
 def relastFiles = fileTree('src/main/jastadd/') {
     include '**/*.relast' }.toList().toArray()
 String[] relastArguments = [
         "../libs/relast.jar",
-        "--grammarName=./src/main/jastadd/StatemachineGen",
+        "--grammarName=./src/gen/jastadd/StatemachineGen",
         "--useJastAddNames",
         "--listClass=ArrayList",
         "--jastAddList=JastAddList",
+        "--resolverHelper",
         "--file"
 ]
 task preprocess(type: JavaExec) {
     group = 'Build'
     main = "-jar"
+
+    doFirst {
+        delete "src/gen/jastadd"
+        mkdir "src/gen/jastadd"
+    }
+
     args relastArguments + relastFiles
 
     inputs.files relastFiles
@@ -78,49 +111,66 @@ task preprocess(type: JavaExec) {
 
 jastadd {
     configureModuleBuild()
-    modules "jastadd_modules"
-    module = "statemachine"
+    modules {
+        module("statemachine") {
+
+            java {
+                basedir "src/"
+                include "main/**/*.java"
+                include "gen/**/*.java"
+            }
+
+            jastadd {
+                basedir "src/"
+                include "main/jastadd/**/*.ast"
+                include "main/jastadd/**/*.jadd"
+                include "main/jastadd/**/*.jrag"
+                include "gen/jastadd/**/*.ast"
+                include "gen/jastadd/**/*.jadd"
+                include "gen/jastadd/**/*.jrag"
+            }
+
+            scanner {
+                include "src/main/jastadd/StateMachineScanner.flex"
+            }
+
+            parser {
+                include "src/main/jastadd/StateMachineParser.parser"
+            }
+        }
+    }
 
-    extraJastAddOptions = ['--List=JastAddList']
+    cleanGen.doFirst {
+        delete "src/gen/java/de"
+        delete "src/gen-res/BuildInfo.properties"
+    }
+
+    module = "statemachine"
 
     astPackage = 'de.tudresden.inf.st.statemachine.jastadd.model'
+
+    parser.name = 'StateMachineParser'
+
     genDir = 'src/gen/java'
 
     buildInfoDir = 'src/gen-res'
-    parser.name = 'StatemachineParser'
 
     scanner.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/scanner"
     parser.genDir = "src/gen/java/de/tudresden/inf/st/statemachine/jastadd/parser"
-}
-
-idea.module.generatedSourceDirs += file('src/gen/java')
-
-sourceSets.main {
-    java {
-        srcDir 'src/gen/java'
-    }
-}
 
-javadoc {
-    // this is only run to get the index file etc.
-    failOnError = false
+    jastaddOptions = ['--List=JastAddList']
 }
 
 String[] arguments = ["../libs/rd-builder.jar", "-d", "doc/"]
 def allSrcFiles = sourceSets.main.allSource.findAll { it.name.endsWith('java') }.toArray()
 def ragdocViewSrcData = '../ragdoc-view/src/data/'
 
-task ragdoc(type: JavaExec, dependsOn: assemble, overwrite: true) {
-    group = 'documentation'
-    description = 'Create ragdoc json documentation files'
-    main = "-jar"
-    args arguments + allSrcFiles
-}
-
-task cleanRagdoc(type: Delete) {
-    group = 'documentation'
-    delete fileTree(ragdocViewSrcData + '/*')
-}
+//task ragdoc(type: JavaExec, dependsOn: assemble, overwrite: true) {
+//    group = 'documentation'
+//    description = 'Create ragdoc json documentation files'
+//    main = "-jar"
+//    args arguments + allSrcFiles
+//}
 
 task copyRagdoc(type: Copy, dependsOn: cleanRagdoc) {
     group = 'documentation'
@@ -131,7 +181,7 @@ task copyRagdoc(type: Copy, dependsOn: cleanRagdoc) {
 }
 
 generateAst.dependsOn preprocess
-generateAst.inputs.files file("./src/main/jastadd/StatemachineGen.ast"), file("./src/main/jastadd/StatemachineGen.jadd")
+//generateAst.inputs.files file("./src/main/jastadd/StatemachineGen.ast"), file("./src/main/jastadd/StatemachineGen.jadd")
 //compileJava.dependsOn jastadd
 //
 //// always run jastadd
diff --git a/statemachine/jastadd_modules b/statemachine/jastadd_modules
deleted file mode 100644
index 0a4da9924785d8df90a13ebeb8f00070dcd31298..0000000000000000000000000000000000000000
--- a/statemachine/jastadd_modules
+++ /dev/null
@@ -1,24 +0,0 @@
-module("statemachine") {
-
-	java {
-		basedir "src/"
-		include "main/**/*.java"
-		include "gen/**/*.java"
-	}
-
-	jastadd {
-		basedir "src/main/jastadd/"
-		include "**/*.ast"
-		include "**/*.jadd"
-		include "**/*.jrag"
-	}
-
-//	scanner {
-//	    include "src/main/jastadd/statemachine.flex"
-//	}
-//
-//	parser {
-//	    include "src/main/jastadd/statemachine.parser"
-//	}
-
-}
diff --git a/statemachine/src/main/jastadd/Analysis.jrag b/statemachine/src/main/jastadd/Analysis.jrag
index 118dd2373e1fb883c829cb8867cb3d898f574e07..427e0b137e9a55d91e59852c7e07a3acb4201e42 100644
--- a/statemachine/src/main/jastadd/Analysis.jrag
+++ b/statemachine/src/main/jastadd/Analysis.jrag
@@ -1,3 +1,32 @@
 aspect Analysis {
+  syn Map<String, State> StateMachine.stateMap() {
+    Map<String, State> map = new HashMap<>();
+    for (State s : states()) {
+      map.put(s.getLabel(), s);
+    }
+    return map;
+  }
 
+  syn Map<String, Transition> StateMachine.transitionMap() {
+    Map<String, Transition> map = new HashMap<>();
+    for (Transition t : transitions()) {
+      map.put(t.getLabel(), t);
+    }
+    return map;
+  }
+
+  syn StateMachine ASTNode.root();
+  eq StateMachine.root() = this;
+  eq ASTNode.root() = getParent().root();
+
+  refine RefResolverStubs eq ASTNode.globallyResolveStateByToken(String id) {
+    return root().stateMap().get(id);
+  }
+
+  refine RefResolverStubs eq ASTNode.globallyResolveTransitionByToken(String id) {
+    return root().transitionMap().get(id);
+  }
+
+  syn boolean State.isInitial() = root().getInitial().equals(this);
+  syn boolean State.isFinal() = root().getFinalList().contains(this);
 }
diff --git a/statemachine/src/main/jastadd/Printing.jrag b/statemachine/src/main/jastadd/Printing.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..5f511fcb7e6374bd7e578185f97a0081322729f6
--- /dev/null
+++ b/statemachine/src/main/jastadd/Printing.jrag
@@ -0,0 +1,12 @@
+aspect Printing {
+  syn String StateMachine.prettyPrint() {
+    StringBuilder sb = new StringBuilder();
+    states().forEach(s -> sb.append(s.prettyPrint()));
+    transitions().forEach(t -> sb.append(t.prettyPrint()));
+    return sb.toString();
+  }
+
+  syn String Element.prettyPrint();
+  eq State.prettyPrint() = (isInitial() ? "initial " : "") + (isFinal() ? "final " : "") + "state " + getLabel() + ";\n";
+  eq Transition.prettyPrint() = "trans " + getFrom().getLabel() + " -> " + getTo().getLabel() + " : " + getLabel() + ";\n";
+}
diff --git a/statemachine/src/main/jastadd/StateMachineParser.parser b/statemachine/src/main/jastadd/StateMachineParser.parser
new file mode 100644
index 0000000000000000000000000000000000000000..197392ec59f05154f50b716da6a4bd92981f1902
--- /dev/null
+++ b/statemachine/src/main/jastadd/StateMachineParser.parser
@@ -0,0 +1,55 @@
+%header {:
+// this code is inlined before the generated parser
+package de.tudresden.inf.st.statemachine.jastadd.parser;
+import de.tudresden.inf.st.statemachine.jastadd.model.*;
+import java.util.*;
+:};
+
+%embed {:
+ // this code is inlined in the generated parser class
+ State initial;
+ List<State> finals = new ArrayList<>();
+:};
+
+%goal goal;
+
+// Productions with semantic actions building the JastAdd AST
+
+statemachine goal =
+  element_list
+    {:
+      StateMachine result = new StateMachine(element_list);
+      result.setInitial(initial);
+      finals.forEach( result::addFinal );
+      return result;
+    :}
+  ;
+
+JastAddList element_list =
+    element                  {: return new JastAddList().add(element); :}
+  | element_list element     {: return element_list.add(element); :}
+  ;
+
+Element element =
+    INITIAL state_body.sb SEMI  {: initial = sb; return sb; :}
+  | FINAL state_body.sb SEMI    {: finals.add(sb); return sb; :}
+  | INITIAL FINAL state_body.sb SEMI  {: initial = sb; finals.add(sb); return sb; :}
+  | state_body.sb SEMI    {: return sb; :}
+  | TRANS NAME.from ARROW NAME.to COLON NAME.label SEMI
+    {:
+      Transition result = new Transition();
+      result.setLabel(label);
+      result.setFrom(State.createRef(from));
+      result.setTo(State.createRef(to));
+      return result;
+    :}
+  ;
+
+State state_body =
+    STATE NAME.name
+    {:
+      State result = new State();
+      result.setLabel(name);
+      return result;
+    :}
+  ;
diff --git a/statemachine/src/main/jastadd/StateMachineScanner.flex b/statemachine/src/main/jastadd/StateMachineScanner.flex
new file mode 100644
index 0000000000000000000000000000000000000000..ad86af4783a0ca7ba0a425bf33204226c493139d
--- /dev/null
+++ b/statemachine/src/main/jastadd/StateMachineScanner.flex
@@ -0,0 +1,45 @@
+package de.tudresden.inf.st.statemachine.jastadd.scanner;
+
+import de.tudresden.inf.st.statemachine.jastadd.parser.StateMachineParser.Terminals; // The terminals are implicitly defined in the parser
+%%
+
+// define the signature for the generated scanner
+%public
+%final
+%class StateMachineScanner
+%extends beaver.Scanner
+
+// the interface between the scanner and the parser is the nextToken() method
+%type beaver.Symbol
+%function nextToken
+%yylexthrow beaver.Scanner.Exception
+
+// store line and column information in the tokens
+%line
+%column
+
+// this code will be inlined in the body of the generated scanner class
+%{
+  private beaver.Symbol sym(short id) {
+    return new beaver.Symbol(id, yyline + 1, yycolumn + 1, yylength(), yytext());
+  }
+%}
+
+WhiteSpace = [ ] | \t | \f | \n | \r | \r\n
+Identifier = [:jletter:][:jletterdigit:]*
+
+%%
+
+// discard whitespace information
+{WhiteSpace}  { }
+
+// token definitions
+"initial"     { return sym(Terminals.INITIAL); }
+"final"       { return sym(Terminals.FINAL); }
+"state"       { return sym(Terminals.STATE); }
+"trans"       { return sym(Terminals.TRANS); }
+{Identifier}  { return sym(Terminals.NAME); }
+";"           { return sym(Terminals.SEMI); }
+":"           { return sym(Terminals.COLON); }
+"->"          { return sym(Terminals.ARROW); }
+<<EOF>>       { return sym(Terminals.EOF); }
diff --git a/statemachine/src/main/jastadd/StatemachineGen.ast b/statemachine/src/main/jastadd/StatemachineGen.ast
deleted file mode 100644
index 52c50cf0dec245e10ba8ba6cad8c1c75a0bcbb3b..0000000000000000000000000000000000000000
--- a/statemachine/src/main/jastadd/StatemachineGen.ast
+++ /dev/null
@@ -1,4 +0,0 @@
-StateMachine ::= Element* <_impl_Final:ArrayList<State>> <_impl_Initial:State>;
-abstract Element ::= <Label:String>;
-State : Element ::= <_impl_Incoming:ArrayList<Transition>> <_impl_Outgoing:ArrayList<Transition>>;
-Transition : Element ::= <_impl_From:State> <_impl_To:State>;
diff --git a/statemachine/src/main/jastadd/StatemachineGen.jadd b/statemachine/src/main/jastadd/StatemachineGen.jadd
deleted file mode 100644
index 045f903487777fb18511e8cc641bfed7298f3926..0000000000000000000000000000000000000000
--- a/statemachine/src/main/jastadd/StatemachineGen.jadd
+++ /dev/null
@@ -1,276 +0,0 @@
-import java.util.ArrayList;
-import java.util.Collections;
-import java.time.Instant;
-import java.time.Period;
-aspect RelAstAPI {
-  class ASTNodeAnnotation {
-    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
-    @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD)
-    @java.lang.annotation.Documented
-    public @interface RelationDoc {
-      String roleName();
-      String targetType();
-    }
-  }
-  public StateMachine.StateMachine(JastAddList<Element> Element) {
-    setElementList(Element);
-  }
-  public State.State(String Label) {
-    setLabel(Label);
-  }
-  public Transition.Transition(String Label) {
-    setLabel(Label);
-  }
-  // rel Transition.From <-> State.Outgoing*
-  /**
-   * @relation From
-   */
-  public State Transition.getFrom() {
-    return get_impl_From();
-  }
-  public Transition Transition.setFrom(State o) {
-    assertNotNull(o);
-    if (tokenState__impl_From != null) {
-      ArrayList<Transition> list2 = tokenState__impl_From.tokenArrayList_Transition___impl_Outgoing;
-      list2.remove(this);
-      tokenState__impl_From.set_impl_Outgoing(list2);
-    }
-    set_impl_From(o);
-    ArrayList<Transition> list = o.tokenArrayList_Transition___impl_Outgoing;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(this);
-    o.set_impl_Outgoing(list);
-    return this;
-  }
-  /**
-   * @relation Outgoing
-   */
-  public java.util.List<Transition> State.getOutgoings() {
-    return getOutgoingList();
-  }
-  public java.util.List<Transition> State.getOutgoingList() {
-    ArrayList<Transition> l = get_impl_Outgoing();
-    return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();
-  }
-  public void State.addOutgoing(Transition o) {
-    assertNotNull(o);
-    if (o != null && o.tokenState__impl_From != null) {
-      ArrayList<Transition> list2 = o.tokenState__impl_From.tokenArrayList_Transition___impl_Outgoing;
-      if (list2.remove(o))
-        o.tokenState__impl_From.set_impl_Outgoing(list2);
-    }
-    ArrayList<Transition> list = tokenArrayList_Transition___impl_Outgoing;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(o);
-    set_impl_Outgoing(list);
-    o.set_impl_From(this);
-  }
-  public void State.addOutgoing(int index, Transition o) {
-    assertNotNull(o);
-    if (o != null && o.tokenState__impl_From != null) {
-      ArrayList<Transition> list2 = o.tokenState__impl_From.tokenArrayList_Transition___impl_Outgoing;
-      if (list2.remove(o))
-        o.tokenState__impl_From.set_impl_Outgoing(list2);
-    }
-    ArrayList<Transition> list = tokenArrayList_Transition___impl_Outgoing;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(index, o);
-    set_impl_Outgoing(list);
-    o.set_impl_From(this);
-  }
-  public void State.removeOutgoing(Transition o) {
-    assertNotNull(o);
-    ArrayList<Transition> list = tokenArrayList_Transition___impl_Outgoing;
-    if (list != null && list.remove(o)) {
-      set_impl_Outgoing(list);
-      if (o.tokenState__impl_From == this) {
-        o.set_impl_From(null);
-      }
-    }
-  }
-
-  // rel Transition.To <-> State.Incoming*
-  /**
-   * @relation To
-   */
-  public State Transition.getTo() {
-    return get_impl_To();
-  }
-  public Transition Transition.setTo(State o) {
-    assertNotNull(o);
-    if (tokenState__impl_To != null) {
-      ArrayList<Transition> list2 = tokenState__impl_To.tokenArrayList_Transition___impl_Incoming;
-      list2.remove(this);
-      tokenState__impl_To.set_impl_Incoming(list2);
-    }
-    set_impl_To(o);
-    ArrayList<Transition> list = o.tokenArrayList_Transition___impl_Incoming;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(this);
-    o.set_impl_Incoming(list);
-    return this;
-  }
-  /**
-   * @relation Incoming
-   */
-  public java.util.List<Transition> State.getIncomings() {
-    return getIncomingList();
-  }
-  public java.util.List<Transition> State.getIncomingList() {
-    ArrayList<Transition> l = get_impl_Incoming();
-    return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();
-  }
-  public void State.addIncoming(Transition o) {
-    assertNotNull(o);
-    if (o != null && o.tokenState__impl_To != null) {
-      ArrayList<Transition> list2 = o.tokenState__impl_To.tokenArrayList_Transition___impl_Incoming;
-      if (list2.remove(o))
-        o.tokenState__impl_To.set_impl_Incoming(list2);
-    }
-    ArrayList<Transition> list = tokenArrayList_Transition___impl_Incoming;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(o);
-    set_impl_Incoming(list);
-    o.set_impl_To(this);
-  }
-  public void State.addIncoming(int index, Transition o) {
-    assertNotNull(o);
-    if (o != null && o.tokenState__impl_To != null) {
-      ArrayList<Transition> list2 = o.tokenState__impl_To.tokenArrayList_Transition___impl_Incoming;
-      if (list2.remove(o))
-        o.tokenState__impl_To.set_impl_Incoming(list2);
-    }
-    ArrayList<Transition> list = tokenArrayList_Transition___impl_Incoming;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(index, o);
-    set_impl_Incoming(list);
-    o.set_impl_To(this);
-  }
-  public void State.removeIncoming(Transition o) {
-    assertNotNull(o);
-    ArrayList<Transition> list = tokenArrayList_Transition___impl_Incoming;
-    if (list != null && list.remove(o)) {
-      set_impl_Incoming(list);
-      if (o.tokenState__impl_To == this) {
-        o.set_impl_To(null);
-      }
-    }
-  }
-
-  // rel StateMachine.Initial -> State
-  /**
-   * @relation Initial
-   */
-  public State StateMachine.getInitial() {
-    return get_impl_Initial();
-  }
-  public StateMachine StateMachine.setInitial(State o) {
-    assertNotNull(o);
-    set_impl_Initial(o);
-    return this;
-  }
-
-  // rel StateMachine.Final* -> State
-  /**
-   * @relation Final
-   */
-  public java.util.List<State> StateMachine.getFinals() {
-    return getFinalList();
-  }
-  public java.util.List<State> StateMachine.getFinalList() {
-    ArrayList<State> l = get_impl_Final();
-    return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();
-  }
-  public void StateMachine.addFinal(State o) {
-    assertNotNull(o);
-    ArrayList<State> list = tokenArrayList_State___impl_Final;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(o);
-    set_impl_Final(list);
-  }
-  public void StateMachine.addFinal(int index, State o) {
-    assertNotNull(o);
-    ArrayList<State> list = tokenArrayList_State___impl_Final;
-    if (list == null) {
-      list = new ArrayList<>();
-    }
-    list.add(index, o);
-    set_impl_Final(list);
-  }
-  public void StateMachine.removeFinal(State o) {
-    assertNotNull(o);
-    ArrayList<State> list = tokenArrayList_State___impl_Final;
-    if (list != null && list.remove(o)) {
-      set_impl_Final(list);
-    }
-  }
-
-  public boolean ASTNode.violatesLowerBounds() {
-    return !getLowerBoundsViolations().isEmpty();
-  }
-  public java.util.List<Pair<ASTNode, String>> ASTNode.getLowerBoundsViolations() {
-    ArrayList<Pair<ASTNode, String>> list = new ArrayList<>();
-    computeLowerBoundsViolations(list);
-    return list;
-  }
-  public void ASTNode.computeLowerBoundsViolations(java.util.List<Pair<ASTNode, String>> list) {
-    for (int i = 0; i < getNumChildNoTransform(); i++) {
-      getChildNoTransform(i).computeLowerBoundsViolations(list);
-    }
-  }
-  public void StateMachine.computeLowerBoundsViolations(java.util.List<Pair<ASTNode, String>> list) {
-    if (getInitial() == null) {
-      list.add(new Pair<>(this, "Initial"));
-    }
-    super.computeLowerBoundsViolations(list);
-  }
-  public void Transition.computeLowerBoundsViolations(java.util.List<Pair<ASTNode, String>> list) {
-    if (getFrom() == null) {
-      list.add(new Pair<>(this, "From"));
-    }
-    if (getTo() == null) {
-      list.add(new Pair<>(this, "To"));
-    }
-    super.computeLowerBoundsViolations(list);
-  }
-  public class Pair<T1, T2> {
-    public final T1 _1;
-    public final T2 _2;
-    public Pair(T1 _1, T2 _2) {
-      ASTNode.assertNotNull(_1);
-      ASTNode.assertNotNull(_2);
-      this._1 = _1;
-      this._2 = _2;
-    }
-    public boolean equals(Object other) {
-      if (other instanceof Pair) {
-        Pair<?,?> p = (Pair<?,?>) other;
-        return _1.equals(p._1) && _2.equals(p._2);
-      } else {
-        return false;
-      }
-    }
-    public int hashCode() {
-      return 31*_1.hashCode() + _2.hashCode();
-    }
-  }
-  public static void ASTNode.assertNotNull(Object obj) {
-    if (obj == null) {
-      throw new NullPointerException();
-    }
-  }
-}
diff --git a/statemachine/src/main/java/de/tudresden/inf/st/statemachine/DrAstRunner.java b/statemachine/src/main/java/de/tudresden/inf/st/statemachine/DrAstRunner.java
new file mode 100644
index 0000000000000000000000000000000000000000..d22a3a3f1faf6bb1639e1fc696d784a17b8cdfdc
--- /dev/null
+++ b/statemachine/src/main/java/de/tudresden/inf/st/statemachine/DrAstRunner.java
@@ -0,0 +1,82 @@
+package de.tudresden.inf.st.statemachine;
+
+import drast.Log;
+import drast.model.DrAST;
+import drast.model.DrASTSettings;
+import drast.model.TreeFilter;
+import drast.views.gui.DrASTGUI;
+import drast.views.gui.GUIData;
+import drast.views.gui.controllers.Controller;
+import drast.views.gui.graph.GraphView;
+import javafx.application.Platform;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.ScrollPane;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+
+/**
+ * Extended runner for DrAST
+ *
+ * @author jmey - Initial contribution
+ */
+public class DrAstRunner extends DrASTGUI {
+
+  public static void main(String[] args) {
+
+    openView();
+    System.exit(0);
+
+  }
+
+  private static final GUIData mon = new GUIData();
+  private static Controller con;
+  private static boolean guiHasBeenCreated = false;
+
+  private static void openView() {
+    guiHasBeenCreated = true;
+    DrASTSettings.put(DrASTSettings.PREV_JAR, "build/libs/statemachine-0.1.jar");
+    launch(new String[0]);
+    con.onApplicationClose();
+  }
+
+  public void setRoot(Object root) {
+    long timeStart = System.currentTimeMillis();
+    DrAST newAst = new DrAST(root, TreeFilter.readFilter(con.getFilter()));
+    Log.info("Filter update: done after %d ms", new Object[]{System.currentTimeMillis() - timeStart});
+    Platform.runLater(() -> {
+      mon.reset(newAst);
+      if (guiHasBeenCreated) {
+        con.onSetRoot();
+      } else {
+        openView();
+      }
+
+    });
+  }
+
+  public void start(Stage stage) throws Exception {
+    FXMLLoader loader = new FXMLLoader();
+    Parent rootView = (Parent)loader.load(this.getClass().getResource("/main.fxml").openStream());
+    con = (Controller)loader.getController();
+    mon.setParentStage(stage);
+    mon.setController(con);
+    mon.setDrASTUI(this);
+    mon.setStage(stage);
+    GraphView graphview = new GraphView(mon);
+    graphview.setOnMouseClicked((event) -> graphview.getParent().requestFocus());
+    mon.setGraphView(graphview);
+    con.init(mon);
+    Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
+    stage.setTitle("DrAST 1.2.2");
+    stage.setScene(new Scene(rootView, primaryScreenBounds.getWidth(), primaryScreenBounds.getHeight() - 100.0D));
+    stage.show();
+    ScrollPane center = (ScrollPane)rootView.lookup("#graphViewScrollPane");
+    center.setContent(graphview);
+    Platform.runLater(() -> graphview.setPreferredSize((int)center.getWidth(), (int)center.getHeight()));
+    con.loadPreviousFilter();
+  }
+
+}
diff --git a/statemachine/src/test/java/de/tudresden/inf/st/statemachine/ParserTest.java b/statemachine/src/test/java/de/tudresden/inf/st/statemachine/ParserTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7628327f4fdc8c58294fab94de040b4e7307971b
--- /dev/null
+++ b/statemachine/src/test/java/de/tudresden/inf/st/statemachine/ParserTest.java
@@ -0,0 +1,98 @@
+package de.tudresden.inf.st.statemachine;
+
+import beaver.Parser;
+import de.tudresden.inf.st.statemachine.jastadd.model.State;
+import de.tudresden.inf.st.statemachine.jastadd.model.StateMachine;
+import de.tudresden.inf.st.statemachine.jastadd.model.Transition;
+import de.tudresden.inf.st.statemachine.jastadd.parser.StateMachineParser;
+import de.tudresden.inf.st.statemachine.jastadd.scanner.StateMachineScanner;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.collection.IsEmptyCollection.empty;
+import static org.junit.Assert.*;
+
+/**
+ * TODO: Add description.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class ParserTest {
+
+  @Test
+  public void test1() throws IOException, Parser.Exception {
+    StateMachine stateMachine = load(Paths.get("src", "test", "resources", "machine_one.sm"));
+
+    assertEquals(6, stateMachine.getNumElement());
+    assertEquals(3, stateMachine.states().size());
+    assertEquals(3, stateMachine.transitions().size());
+
+    State s = stateMachine.globallyResolveStateByToken("S");
+    State a = stateMachine.globallyResolveStateByToken("A");
+    State e = stateMachine.globallyResolveStateByToken("E");
+    Transition t1 = stateMachine.globallyResolveTransitionByToken("t1");
+    Transition t2 = stateMachine.globallyResolveTransitionByToken("t2");
+    Transition t3 = stateMachine.globallyResolveTransitionByToken("t3");
+
+    assertNotNull(s);
+    assertNotNull(a);
+    assertNotNull(e);
+
+    assertEquals(s, stateMachine.getInitial());
+    assertEquals(1, stateMachine.getFinalList().size());
+    assertThat("E is not final", stateMachine.getFinalList(), hasItem(e));
+
+    assertNotNull(t1);
+    assertNotNull(t2);
+    assertNotNull(t3);
+
+    // t1: s -> a
+    assertEquals(s, t1.getFrom());
+    assertEquals(a, t1.getTo());
+    // t2: a -> s
+    assertEquals(a, t2.getFrom());
+    assertEquals(s, t2.getTo());
+    // t3: a -> e
+    assertEquals(a, t3.getFrom());
+    assertEquals(e, t3.getTo());
+
+    List<State> outgoingFromS = outgoingConnectedStates(s);
+    List<State> outgoingFromA = outgoingConnectedStates(a);
+    assertThat(outgoingFromS, not(empty()));
+    assertThat(outgoingFromA, not(empty()));
+    assertEquals(1, outgoingFromS.size());
+    assertThat("Transition S -> A missing", outgoingFromS, hasItem(a));
+    assertEquals(2, outgoingFromA.size());
+    assertThat("Transitions A -> S or A -> E missing", outgoingFromA, hasItems(s, e));
+    assertThat(outgoingConnectedStates(e), empty());
+
+    String printedForm = "initial state S;\n" +
+        "state A;\n" +
+        "final state E;\n" +
+        "trans S -> A : t1;\n" +
+        "trans A -> S : t2;\n" +
+        "trans A -> E : t3;\n";
+    assertEquals(printedForm, stateMachine.prettyPrint());
+  }
+
+  private List<State> outgoingConnectedStates(State s) {
+    return s.getOutgoingList().stream().map(Transition::getTo).collect(Collectors.toList());
+  }
+
+  private static StateMachine load(Path path) throws IOException, Parser.Exception {
+    Reader reader = Files.newBufferedReader(path);
+    StateMachineScanner scanner = new StateMachineScanner(reader);
+    StateMachineParser parser = new StateMachineParser();
+    StateMachine result = (StateMachine) parser.parse(scanner);
+    reader.close();
+    return result;
+  }
+}
diff --git a/statemachine/src/test/resources/machine_one.sm b/statemachine/src/test/resources/machine_one.sm
new file mode 100644
index 0000000000000000000000000000000000000000..897ccba6b19229216233f9c8b8af57ac03bf8852
--- /dev/null
+++ b/statemachine/src/test/resources/machine_one.sm
@@ -0,0 +1,6 @@
+initial state S;
+state A;
+final state E;
+trans S -> A : t1;
+trans A -> S : t2;
+trans A -> E : t3;