diff --git a/dumpAst2uml/.gitignore b/dumpAst2uml/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..87b4cdd3d7c6a41502ca98703abeeb69a1d536fb
--- /dev/null
+++ b/dumpAst2uml/.gitignore
@@ -0,0 +1,5 @@
+build
+src/gen-res/
+src/gen/
+out/
+*.class
diff --git a/dumpAst2uml/build.gradle b/dumpAst2uml/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7690a02f55330f0f0c199bbf94cdfcd285912e72
--- /dev/null
+++ b/dumpAst2uml/build.gradle
@@ -0,0 +1,188 @@
+apply plugin: 'jastadd'
+apply plugin: 'application'
+apply plugin: 'idea'
+
+sourceCompatibility = 1.8
+
+mainClassName = 'org.jastadd.dumpAst2uml.compiler.Compiler'
+
+repositories {
+    jcenter()
+}
+
+buildscript {
+    repositories.jcenter()
+    dependencies {
+        classpath 'org.jastadd:jastaddgradle:1.13.3'
+    }
+}
+
+dependencies {
+    implementation project(':grammar2uml')  // just to test SimpleMain
+    implementation project(':relast.preprocessor')
+
+    implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.9.6'
+    implementation group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.11.2'
+    runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
+    api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
+
+    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.0'
+    testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0'
+    testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.12.1'
+}
+
+def versionFile = 'src/main/resources/dumpAst2umlVersion.properties'
+def oldProps = new Properties()
+
+try {
+    file(versionFile).withInputStream { stream -> oldProps.load(stream) }
+    version = oldProps['version']
+} catch (e) {
+    // this happens, if either the properties file is not present, or cannot be read from
+    throw new GradleException("File ${versionFile} not found or unreadable. Aborting.")
+}
+
+task newVersion() {
+    doFirst {
+        def props = new Properties()
+        props['version'] = value
+        props.store(file(versionFile).newWriter(), null)
+    }
+}
+
+jar {
+    manifest {
+        attributes "Main-Class": mainClassName
+    }
+
+    from {
+        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
+    }
+
+    archiveBaseName = 'dumpAst2uml'
+}
+
+File genSrc = file("src/gen/java")
+sourceSets.main.java.srcDir genSrc
+idea.module.generatedSourceDirs += genSrc
+
+test {
+    useJUnitPlatform()
+
+    maxHeapSize = '1G'
+}
+
+//task relast(type: JavaExec) {
+//    group = 'Build'
+//    main = "-jar"
+//
+//    doFirst {
+//        delete "src/gen/jastadd/*.ast"
+//        delete "src/gen/jastadd/Grammar2Uml.jadd"
+//        delete "src/gen/jastadd/Grammar2UmlRefResolver.jadd"
+//        delete "src/gen/jastadd/Grammar2UmlResolverStubs.jrag"
+//        mkdir  "src/gen/jastadd/"
+//    }
+//
+//    args = [
+//            "../libs/relast.jar",
+//            "../relast.preprocessor/src/main/jastadd/RelAst.relast",
+//            "./src/main/jastadd/Grammar2Uml.relast",
+//            "./src/main/jastadd/MustacheNodes.relast",
+//            "--listClass=java.util.ArrayList",
+//            "--jastAddList=JastAddList",
+//            "--useJastAddNames",
+//            "--file",
+//            "--resolverHelper",
+//            "--grammarName=./src/gen/jastadd/Grammar2Uml"
+//    ]
+//
+////    inputs.files file("../libs/relast.jar"),
+////            file("../relast.preprocessor/src/main/jastadd/RelAST.relast"),
+////            file("./src/main/jastadd/Grammar2Uml.relast")
+////            file("./src/main/jastadd/MustacheNodes.relast")
+////    outputs.files file("./src/gen/jastadd/Grammar2Uml.ast"),
+////            file("./src/gen/jastadd/Grammar2Uml.jadd"),
+////            file("./src/gen/jastadd/Grammar2UmlRefResolver.jadd"),
+////            file('./src/gen/jastadd/Grammar2UmlResolverStubs.jrag')
+//}
+//
+//jastadd {
+//    configureModuleBuild()
+//    modules {
+//        //noinspection GroovyAssignabilityCheck
+//        module("Grammar2Uml") {
+//
+//            java {
+//                basedir ".."
+//                include "relast.preprocessor/main/**/*.java"
+//                include "relast.preprocessor/gen/**/*.java"
+//                include "dumpAst2uml/src/main/**/*.java"
+//                include "dumpAst2uml/src/gen/**/*.java"
+//            }
+//
+//            jastadd {
+//                basedir ".."
+//                include "relast.preprocessor/src/main/jastadd/**/*.ast"
+//                include "relast.preprocessor/src/main/jastadd/**/*.jadd"
+//                include "relast.preprocessor/src/main/jastadd/**/*.jrag"
+//                include "dumpAst2uml/src/main/jastadd/**/*.ast"
+//                include "dumpAst2uml/src/main/jastadd/**/*.jadd"
+//                include "dumpAst2uml/src/main/jastadd/**/*.jrag"
+//                include "dumpAst2uml/src/gen/jastadd/**/*.ast"
+//                include "dumpAst2uml/src/gen/jastadd/**/*.jadd"
+//                include "dumpAst2uml/src/gen/jastadd/**/*.jrag"
+//            }
+//
+//            scanner {
+//                basedir ".."
+//                include "dumpAst2uml/src/main/jastadd/scanner/Header.flex",               [-5]
+//                include "relast.preprocessor/src/main/jastadd/scanner/Preamble.flex",      [-4]
+//                include "relast.preprocessor/src/main/jastadd/scanner/Macros.flex",        [-3]
+//                include "dumpAst2uml/src/main/jastadd/scanner/Macros.flex",               [-3]
+//                include "relast.preprocessor/src/main/jastadd/scanner/RulesPreamble.flex", [-2]
+//                include "dumpAst2uml/src/main/jastadd/scanner/MappingContent.flex",       [-1]
+//                include "dumpAst2uml/src/main/jastadd/scanner/Keywords.flex"
+//                include "relast.preprocessor/src/main/jastadd/scanner/Keywords.flex"
+//                include "relast.preprocessor/src/main/jastadd/scanner/Symbols.flex",        [1]
+//                include "relast.preprocessor/src/main/jastadd/scanner/RulesPostamble.flex", [2]
+//            }
+//
+//            parser {
+//                basedir ".."
+//                include "dumpAst2uml/src/main/jastadd/parser/Preamble.parser"
+//                include "relast.preprocessor/src/main/jastadd/parser/RelAst.parser"
+//                include "dumpAst2uml/src/main/jastadd/parser/Grammar2Uml.parser"
+//            }
+//        }
+//    }
+//
+//    cleanGen.doFirst {
+//        delete "src/gen/java/org"
+//        delete "src/gen-res/BuildInfo.properties"
+//    }
+//
+//    preprocessParser.doFirst {
+//
+//        args += ["--no-beaver-symbol"]
+//
+//    }
+//
+//    module = "Grammar2Uml"
+//
+//    astPackage = 'org.jastadd.dumpAst2uml.ast'
+//
+//    parser.name = 'Grammar2UmlParser'
+//
+//    genDir = 'src/gen/java'
+//
+//    buildInfoDir = 'src/gen-res'
+//
+//    scanner.genDir = "src/gen/java/org/jastadd/dumpAst2uml/scanner"
+//    parser.genDir = "src/gen/java/org/jastadd/dumpAst2uml/parser"
+//
+//    jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
+//}
+//
+//generateAst.dependsOn relast
diff --git a/dumpAst2uml/src/main/java/org/jastadd/dumpAst2uml/compiler/SimpleMain.java b/dumpAst2uml/src/main/java/org/jastadd/dumpAst2uml/compiler/SimpleMain.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ccafbacb5e000da51f5fffb936ef63c6574116b
--- /dev/null
+++ b/dumpAst2uml/src/main/java/org/jastadd/dumpAst2uml/compiler/SimpleMain.java
@@ -0,0 +1,153 @@
+package org.jastadd.dumpAst2uml.compiler;
+
+import beaver.Parser;
+import org.jastadd.grammar2uml.ast.*;
+import org.jastadd.grammar2uml.parser.Grammar2UmlParser;
+import org.jastadd.grammar2uml.scanner.Grammar2UmlScanner;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Testing Relast2Uml without parser.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class SimpleMain {
+
+  public static void main(String[] args) {
+//    testing();
+    createManualAST();
+  }
+
+  private static void createManualAST() {
+    System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
+    System.setProperty("mustache.debug", "true");
+    Grammar2Uml model = new Grammar2Uml();
+    Path path = Paths.get("grammar2uml", "src", "test", "resources", "Example.relast");
+    System.out.println("path.toFile().getAbsolutePath() = " + path.toFile().getAbsolutePath());
+    Program program = parseProgram(path);
+    model.setProgram(program);
+
+    Folder folder1 = new Folder();
+    folder1.setName("Folder1");
+    folder1.addType(program.resolveTypeDecl("Wert"));
+    folder1.addType(program.resolveTypeDecl("Quelle"));
+    model.addFolder(folder1);
+
+    model.treeResolveAll();
+    traverseInitial(model.toMustache());
+  }
+
+  static final String MORE_INDENT = "| ";
+
+  private static void traverseInitial(Object obj) {
+    traverse(obj, new HashSet<>(), "");
+  }
+
+  private static void traverse(Object obj, Set<Object> seen, String indent) {
+    if (seen.contains(obj)) {
+      return;
+    }
+    seen.add(obj);
+    System.out.println(indent + "|> " + obj.toString());
+    System.out.println(indent + "| isAstNode(obj) = " + isAstNode(obj));
+    printChildren(obj, seen, indent);
+    printTokens(obj, seen, indent);
+  }
+
+  private static boolean isAstNode(Object obj) {
+    Class<?> clazz = obj.getClass();
+    for (Constructor<?> constructor : clazz.getConstructors()) {
+      if (constructor.isAnnotationPresent(ASTNodeAnnotation.Constructor.class)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static void printChildren(Object obj, Set<Object> seen, String indent) {
+    Class<?> clazz = obj.getClass();
+    for (Method method : clazz.getMethods()) {
+      final String name;
+      final String kind;
+      if (method.isAnnotationPresent(ASTNodeAnnotation.Child.class)) {
+        name = method.getAnnotation(ASTNodeAnnotation.Child.class).name();
+        kind = "";
+      } else if (method.isAnnotationPresent(ASTNodeAnnotation.ListChild.class)) {
+        name = method.getAnnotation(ASTNodeAnnotation.ListChild.class).name();
+        kind = "list-";
+      } else if (method.isAnnotationPresent(ASTNodeAnnotation.OptChild.class)) {
+        name = method.getAnnotation(ASTNodeAnnotation.OptChild.class).name();
+        kind = "opt-";
+      } else {
+        name = null;
+        kind = null;
+      }
+      if (kind != null) {
+        try {
+          Object child = method.invoke(obj);
+          System.out.println(indent + "| " + kind + "child (" + name + ") = " + child);
+          traverse(child, seen, indent + MORE_INDENT);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+
+  static void printTokens(Object obj, Set<Object> seen, String indent) {
+    Class<?> clazz = obj.getClass();
+    for (Method method : clazz.getMethods()) {
+      if (method.isAnnotationPresent(ASTNodeAnnotation.Token.class)) {
+        Method methodToInvoke = null;
+        String name = method.getAnnotation(ASTNodeAnnotation.Token.class).name();
+        // heuristic for relations
+        if (name.startsWith("_impl_")) {
+          try {
+            methodToInvoke = clazz.getMethod("get" + name.substring(6));
+            name = name.substring(6);
+          } catch (NoSuchMethodException e) {
+            // this is probably not a relation
+          }
+        }
+        final String kind;
+        if (methodToInvoke == null) {
+          methodToInvoke = method;
+          kind = "token";
+        } else {
+          kind = "relation";
+        }
+        try {
+          Object value = methodToInvoke.invoke(obj);
+          System.out.println(indent + "| " + kind + " (" + name + ") = " + value);
+          traverse(value, seen, indent + MORE_INDENT);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+
+  private static Program parseProgram(Path path) {
+    try (BufferedReader reader = Files.newBufferedReader(path)) {
+      Grammar2UmlScanner scanner = new Grammar2UmlScanner(reader);
+      Grammar2UmlParser parser = new Grammar2UmlParser();
+      GrammarFile grammarFile = (GrammarFile) parser.parse(scanner);
+      Program program = new Program();
+      program.addGrammarFile(grammarFile);
+      return program;
+    } catch (IOException | Parser.Exception e) {
+      e.printStackTrace();
+    }
+    return null;
+  }
+}
diff --git a/settings.gradle b/settings.gradle
index eb0d566fd20cf8b162d936b2b7ec901310be1418..3278510c64b72f36f4d307f08eea5f134a2d99d9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,3 +2,4 @@ rootProject.name = 'relast2uml'
 
 include 'relast.preprocessor'
 include 'grammar2uml'
+include 'dumpAst2uml'