diff --git a/dumpAst/build.gradle b/dumpAst/build.gradle
index b6793149b06ba134d59ad0886d55eda83be58b20..458affa6a834bd7c3f3c0da8578ed904466c8084 100644
--- a/dumpAst/build.gradle
+++ b/dumpAst/build.gradle
@@ -14,8 +14,11 @@ plugins {
 apply plugin: 'jastadd'
 
 dependencies {
-    jastadd2 "org.jastadd:jastadd:2.3.4"
-    implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "${mustache_java_version}"
+    jastadd2 "org.jastadd:jastadd:2.3.5"
+    implementation fileTree(include: ['plantuml.jar'], dir: '../libs')
+//    implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "0.9.10"
+    implementation group: 'com.github.jknack', name: 'handlebars', version: '4.2.0'
+    implementation group: 'org.yaml', name: 'snakeyaml', version: '1.27'
 }
 
 File dumpAstGrammar = file('./src/main/jastadd/DumpAst.relast')
diff --git a/dumpAst/src/main/jastadd/GenerationBackend.jadd b/dumpAst/src/main/jastadd/GenerationBackend.jadd
index 44f62835e1c79d0a58a919a979928a9c3fdb782e..4f360f02d9b6da3c21fdf1b25d19a5e8692f9eb8 100644
--- a/dumpAst/src/main/jastadd/GenerationBackend.jadd
+++ b/dumpAst/src/main/jastadd/GenerationBackend.jadd
@@ -491,8 +491,8 @@ aspect GenerationBackend {
     return p.matcher(input).matches();
   }
 
-  // --- version --- (mustache has buildConfig as context)
-  syn String BuildConfig.version() = printConfig().getVersion();
+  // --- debug --- (mustache has printConfig as context)
+  syn boolean PrintConfig.debug() = buildConfig().getDebug();
 
   private static String DumpAst.invokeName(java.lang.annotation.Annotation annotation) {
     return (String) invokeMethod("name", annotation);
@@ -597,85 +597,6 @@ aspect GenerationBackend {
     int nodeCounter = 0;
   }
 
-  syn String DumpAst.toYaml(boolean prependCreationComment) {
-    Document doc = new Document();
-    doc.setRootElement(getRootNode().toYaml());
-    return doc.prettyPrint(prependCreationComment);
-  }
-
-  syn MappingElement DumpNode.toYaml() {
-    MappingElement result = new MappingElement();
-    // tokens are key-value-pairs
-    for (DumpToken token : getDumpTokenList()) {
-      if (token.isDumpValueToken()) {
-        result.put(token.getName(), makeValueElement(token.asDumpValueToken().getValue()));
-      } else {
-        result.put(token.getName(), token.asDumpReferenceToken().getValue().toYaml());
-      }
-    }
-    // children
-    for (DumpChildNode child : getDumpChildNodeList()) {
-      ListElement list = new ListElement();
-      for (DumpNode inner : child.innerNodes(true)) {
-        list.add(inner.toYaml());
-      }
-      if (child.isList()) {
-        result.put(child.getName(), list);
-      } else if (list.getNumElement() == 1) {
-        result.put(child.getName(), list.getElement(0));
-      }
-    }
-    // relations
-    for (DumpRelation relation : getDumpRelationList()) {
-      ListElement list = new ListElement();
-      for (DumpNode inner : relation.innerNodes(true)) {
-        list.add(inner.toYaml());
-      }
-      if (relation.isList()) {
-        result.put(relation.getName(), list);
-      } else if (list.getNumElement() == 1) {
-        result.put(relation.getName(), list.getElement(0));
-      }
-    }
-    return result;
-  }
-
-  private static ComplexElement ASTNode.HELPER_COMPLEX_ELEMENT = new MappingElement();
-  protected static Element ASTNode.makeValueElement(Object obj) {
-    if (obj instanceof Integer) {
-      return ValueElement.of((int) obj);
-    } else if (obj instanceof Boolean) {
-      return ValueElement.of((boolean) obj);
-    } else {
-      return HELPER_COMPLEX_ELEMENT.makeStringElement(obj.toString());
-    }
-  }
-
-  public class AppendableWriter extends java.io.Writer {
-    private final StringBuilder sb;
-
-    public AppendableWriter(StringBuilder sb) {
-      this.sb = sb;
-    }
-
-    @Override
-    public void write(char[] chars, int off, int len) {
-      sb.append(chars, off, len);
-    }
-
-    @Override
-    public void write(String str) {
-      sb.append(str);
-    }
-
-    @Override
-    public void flush() {
-    }
-
-    @Override
-    public void close() {
-    }
-  }
 
   static StyleInformation StyleInformation.createDefault() {
     StyleInformation result = new StyleInformation();
diff --git a/dumpAst/src/main/jastadd/GenerationFrontend.jadd b/dumpAst/src/main/jastadd/GenerationFrontend.jadd
index 97b622a1ba1d333ad23e44dabb0a8571721cf6ab..2e168e7cb373393c1c1dc3d741804ecb5518eb7f 100644
--- a/dumpAst/src/main/jastadd/GenerationFrontend.jadd
+++ b/dumpAst/src/main/jastadd/GenerationFrontend.jadd
@@ -406,5 +406,32 @@ public class DumpBuilder {
       }
       return this;
     }
+
+    /**
+     * Write out content as PNG image generated by plantuml.
+     * @param destination path of destination file
+     * @return this
+     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+     */
+    public DumpBuilder dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException {
+      String content = build().toPlantUml();
+      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
+      reader.outputImage(java.nio.file.Files.newOutputStream(destination));
+      return this;
+    }
+
+    /**
+     * Write out content as SVG image generated by plantuml.
+     * @param destination path of destination file
+     * @return this
+     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
+     */
+    public DumpBuilder dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException {
+      String content = build().toPlantUml();
+      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
+      reader.outputImage(java.nio.file.Files.newOutputStream(destination),
+          new net.sourceforge.plantuml.FileFormatOption(net.sourceforge.plantuml.FileFormat.SVG));
+      return this;
+    }
   }
 }
diff --git a/dumpAst/src/main/jastadd/GenerationMustache.jrag b/dumpAst/src/main/jastadd/GenerationMustache.jrag
deleted file mode 100644
index d69f4fba573580285101ce63946da0fda5ce52fd..0000000000000000000000000000000000000000
--- a/dumpAst/src/main/jastadd/GenerationMustache.jrag
+++ /dev/null
@@ -1,25 +0,0 @@
-aspect GenerationMustache {
-  syn String DumpAst.toPlantUml() {
-    StringBuilder sb = new StringBuilder();
-    com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() {
-      @Override
-      public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) {
-        return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) {
-          @Override
-          protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) {
-            com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes);
-            if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) {
-              throw new com.github.mustachejava.MustacheException(name + " not found in " + tc);
-            }
-            return wrapper;
-          }
-        };
-      }
-    };
-    com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory();
-    mf.setObjectHandler(roh);
-    com.github.mustachejava.Mustache m = mf.compile("dumpAst.mustache");
-    m.execute(new java.io.PrintWriter(new AppendableWriter(sb)), this);
-    return sb.toString();
-  }
-}
diff --git a/dumpAst/src/main/jastadd/GenerationToPlantUml.jrag b/dumpAst/src/main/jastadd/GenerationToPlantUml.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..fb117927f3f70723fb3445b8efe9174ee8ee3c66
--- /dev/null
+++ b/dumpAst/src/main/jastadd/GenerationToPlantUml.jrag
@@ -0,0 +1,67 @@
+aspect GenerationToPlantUml {
+  syn String DumpAst.toPlantUml() {
+    try {
+      //Context context = Context
+      //    .newBuilder(this)
+      //    .resolver(
+      //        com.github.jknack.handlebars.context.JavaBeanValueResolver.INSTANCE,
+      //        com.github.jknack.handlebars.context.MethodValueResolver.INSTANCE
+      //    )
+      //    .build();
+      String yaml = this.toYaml(false);
+      Object context = new org.yaml.snakeyaml.Yaml().load(new StringReader(yaml));
+
+      return getTemplate("dumpAst").apply(context);
+    } catch (java.io.IOException e) {
+      return "\nAn Error occured:\n" + e.getMessage();
+    }
+  }
+
+  private static void DumpAst.applyTemplate(String templateFileName, String outputFileName, Object context) throws java.io.IOException {
+    try (java.io.Writer w = new java.io.FileWriter(outputFileName)) {
+      getTemplate(templateFileName).apply(context, w);
+      w.flush();
+    }
+  }
+
+  private static com.github.jknack.handlebars.Template DumpAst.getTemplate(String templateFileName) throws java.io.IOException {
+    com.github.jknack.handlebars.io.TemplateLoader loader = new com.github.jknack.handlebars.io.ClassPathTemplateLoader();
+    loader.setSuffix(".mustache"); // the default is ".hbs"
+
+    com.github.jknack.handlebars.Handlebars handlebars = new com.github.jknack.handlebars.Handlebars(loader);
+    handlebars.registerHelperMissing(new Helper<Object>() {
+        @Override
+        public CharSequence apply(final Object context, final Options options) throws IOException {
+          return options.fn.text();
+        }
+    });
+    handlebars.prettyPrint(true); // set handlebars to mustache mode (skip some whitespace)
+    return handlebars.compile(templateFileName);
+  }
+
+  public class AppendableWriter extends java.io.Writer {
+    private final StringBuilder sb;
+
+    public AppendableWriter(StringBuilder sb) {
+      this.sb = sb;
+    }
+
+    @Override
+    public void write(char[] chars, int off, int len) {
+      sb.append(chars, off, len);
+    }
+
+    @Override
+    public void write(String str) {
+      sb.append(str);
+    }
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public void close() {
+    }
+  }
+}
diff --git a/dumpAst/src/main/jastadd/GenerationToYaml.jrag b/dumpAst/src/main/jastadd/GenerationToYaml.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..9e043dcf51f07487c01075f6596d24a55db06b60
--- /dev/null
+++ b/dumpAst/src/main/jastadd/GenerationToYaml.jrag
@@ -0,0 +1,208 @@
+aspect GenerationToYaml {
+  syn String DumpAst.toYaml(boolean prependCreationComment) {
+    Document doc = new Document();
+    doc.setRootElement(this.toYaml());
+    return doc.prettyPrint(prependCreationComment);
+  }
+
+  // todo: default impl should actually be abstract instead
+  syn MappingElement ASTNode.toYaml() = new MappingElement();
+
+  static MappingElement ASTNode.safeToYaml(ASTNode node) {
+    if (node == null) {
+      return null;
+    }
+    return node.toYaml();
+  }
+
+  syn MappingElement DumpAst.toYaml() {
+    MappingElement result = new MappingElement();
+    // children
+    result.put("PrintConfig", safeToYaml(getPrintConfig()));
+    addYamledList(result, "DumpNodes", getDumpNodeList());
+    return result;
+  }
+
+  static void ASTNode.addYamledList(MappingElement base, String key, Iterable<? extends ASTNode<?>> iterable) {
+    ListElement innerList = new ListElement();
+    for (ASTNode node : iterable) {
+      innerList.add(safeToYaml(node));
+    }
+    base.put(key, innerList);
+  }
+
+  syn MappingElement PrintConfig.toYaml() {
+    MappingElement result = new MappingElement();
+    // children
+    addYamledList(result, "Headers", getHeaderList());
+
+    // tokens
+    result.put("scale", getScale());
+    result.put("version", getVersion());
+    result.put("orderChildren", getOrderChildren());
+
+    // attributes
+    result.put("debug", debug());
+    return result;
+  }
+
+  syn MappingElement Header.toYaml() {
+    MappingElement result = new MappingElement();
+    // tokens
+    result.put("value", getValue());
+    return result;
+  }
+
+  syn MappingElement DumpNode.toYaml() {
+    return toYaml(false);
+  }
+  syn MappingElement DumpNode.toYaml(boolean fromMyChildren) {
+    MappingElement result = new MappingElement();
+
+    // children
+    if (!fromMyChildren) {
+      addYamledList(result, "DumpChildNodes", getDumpChildNodeList());
+      addYamledList(result, "DumpTokens", getDumpTokenList());
+      addYamledList(result, "DumpRelations", getDumpRelationList());
+    }
+
+    // tokens
+    result.put("name", getName());
+    if (!fromMyChildren) {
+      result.put("label", getLabel());
+      result.put("backgroundColor", getBackgroundColor());
+      result.put("textColor", getTextColor());
+      result.put("invisible", getInvisible());
+    }
+
+    // attributes
+    if (!fromMyChildren) {
+      result.put("isAstNode", isAstNode());
+      result.put("labelAndTextColor", labelAndTextColor());
+      addYamledList(result, "myChildren", myChildren());
+    }
+    result.put("hasSuccessor", hasSuccessor());
+    result.put("successor", safeToYaml(successor()));
+
+    // NTAs
+    if (!fromMyChildren) {
+      result.put("InvisiblePath", safeToYaml(getInvisiblePath()));
+    }
+    return result;
+  }
+
+  syn MappingElement DumpChildNode.toYaml() {
+    MappingElement result = new MappingElement();
+    // tokens
+    result.put("name", getName());
+    // attributes
+    result.put("label", label());
+    result.put("isList", isList());
+    result.put("outerNodeName", outerNodeName());
+
+    return result;
+  }
+
+  syn MappingElement DumpNormalChildNode.toYaml() {
+    MappingElement result = super.toYaml();
+    // attributes
+    result.put("bothVisible", bothVisible());
+    result.put("innerNodeName", innerNodeName());
+    return result;
+  }
+
+  syn MappingElement DumpListChildNode.toYaml() {
+    MappingElement result = super.toYaml();
+    // children
+    addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList());
+    return result;
+  }
+
+  syn MappingElement DumpToken.toYaml() {
+    MappingElement result = new MappingElement();
+    // tokens
+    result.put("name", getName());
+    // attributes
+    result.put("label", label());
+    result.put("isDumpValueToken", isDumpValueToken());
+    return result;
+  }
+
+  syn MappingElement DumpValueToken.toYaml() {
+    MappingElement result = super.toYaml();
+    // tokens
+    result.put("value", getValue().toString());
+    return result;
+  }
+
+  syn MappingElement DumpReferenceToken.toYaml() {
+    MappingElement result = super.toYaml();
+    // tokens
+    result.put("innerNodeName", innerNodeName());
+    result.put("outerNodeName", outerNodeName());
+    return result;
+  }
+
+  syn MappingElement DumpRelation.toYaml() {
+    MappingElement result = new MappingElement();
+    // tokens
+    result.put("name", getName());
+    result.put("bidirectional", getBidirectional());
+    // attributes
+    result.put("isList", isList());
+    result.put("label", label());
+    result.put("outerNodeName", outerNodeName());
+    return result;
+  }
+
+  syn MappingElement DumpNormalRelation.toYaml() {
+    MappingElement result = super.toYaml();
+    // attributes
+    result.put("bothVisible", bothVisible());
+    result.put("innerNodeName", innerNodeName());
+    return result;
+  }
+
+  syn MappingElement InnerDumpNode.toYaml() {
+    MappingElement result = new MappingElement();
+    // attributes
+    result.put("bothVisible", bothVisible());
+    result.put("innerNodeName", innerNodeName());
+    result.put("outerNodeName", outerNodeName());
+    return result;
+  }
+
+  syn MappingElement InvisiblePath.toYaml() {
+    MappingElement result = super.toYaml();
+    // children
+    addYamledList(result, "InnerDumpNodes", getInnerDumpNodeList());
+    return result;
+  }
+
+  // extension for mustache
+  public static ValueElement ValueElement.of(double value) {
+    return new ValueElement(false, String.valueOf(value));
+  }
+  public MappingElement MappingElement.put(String key, double value) {
+    addKeyValuePair(key, ValueElement.of(value));
+    return this;
+  }
+
+  refine Helpers public void MappingElement.addKeyValuePair(String key, Element value) {
+    if (value == null) {
+      return;
+    }
+    refined(key, value);
+  }
+
+  refine Helpers protected SimpleElement ComplexElement.makeStringElement(String value) {
+    if (value == null || value.equals("null")) {
+      return StringElement.of("null");
+    }
+    if (value.isEmpty()) {
+      return StringElement.of(value);
+    }
+    return refined(value);
+  }
+
+}
diff --git a/dumpAst/src/main/jastadd/Imports.jadd b/dumpAst/src/main/jastadd/Imports.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..b3d9137d1a1b3814d992c4a0e1715f254b730455
--- /dev/null
+++ b/dumpAst/src/main/jastadd/Imports.jadd
@@ -0,0 +1,6 @@
+import java.io.*;
+import java.util.*;
+import com.github.jknack.handlebars.*;
+import com.github.jknack.handlebars.io.*;
+
+aspect Imports {}
diff --git a/dumpAst/src/main/jastadd/Navigation.jrag b/dumpAst/src/main/jastadd/Navigation.jrag
index 05f722dc7d9cf9097f960598bc45b9c7f1a3a260..b7274955af50bd11e5c902931f3e9f67ca55f3d4 100644
--- a/dumpAst/src/main/jastadd/Navigation.jrag
+++ b/dumpAst/src/main/jastadd/Navigation.jrag
@@ -7,6 +7,7 @@ aspect Navigation {
 
   // --- buildConfig ---
   inh BuildConfig DumpNode.buildConfig();
+  inh BuildConfig PrintConfig.buildConfig();
   eq DumpAst.getChild().buildConfig() = getBuildConfig();
 
   // --- printConfig ---
diff --git a/dumpAst/src/main/resources/dumpAst.mustache b/dumpAst/src/main/resources/dumpAst.mustache
index 78356e35c4b0fc9aa6246fe7be3d24de2b44eb85..32c9a4752050883216ebf1bb1a7b897032c12e7f 100644
--- a/dumpAst/src/main/resources/dumpAst.mustache
+++ b/dumpAst/src/main/resources/dumpAst.mustache
@@ -1,32 +1,32 @@
 @startuml
 {{#PrintConfig}}
-scale {{{Scale}}}
+scale {{{scale}}}
   {{#Headers}}
-{{{Value}}}
+{{{value}}}
   {{/Headers}}
 {{/PrintConfig}}
 
 {{#DumpNodes}}
   {{#isAstNode}}
-    {{^Invisible}}
+    {{^invisible}}
 object "{{{labelAndTextColor}}}" as {{{name}}} {{#backgroundColor}}#{{{backgroundColor}}}{{/backgroundColor}} {
       {{#DumpTokens}}
         {{#isDumpValueToken}}
-  {{{label}}} = {{{Value}}}
+  {{{label}}} = {{{value}}}
         {{/isDumpValueToken}}
       {{/DumpTokens}}
 }
-    {{/Invisible}}
+    {{/invisible}}
   {{/isAstNode}}
 {{/DumpNodes}}
 
 {{#DumpNodes}}
   {{#DumpTokens}}
-    {{^Invisible}}
+    {{^invisible}}
       {{^isDumpValueToken}}
 {{{outerNodeName}}} ..> {{{innerNodeName}}} : {{{label}}}
       {{/isDumpValueToken}}
-    {{/Invisible}}
+    {{/invisible}}
   {{/DumpTokens}}
   {{#DumpChildNodes}}
     {{#isList}}
@@ -46,23 +46,23 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{#backgroundColor}}#{{{backgroun
     {{#isList}}
       {{#InnerDumpNodes}}
         {{#bothVisible}}
-{{{outerNodeName}}} {{#Bidirectional}}<{{/Bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
         {{/bothVisible}}
       {{/InnerDumpNodes}}
     {{/isList}}
     {{^isList}}
       {{#bothVisible}}
-{{{outerNodeName}}} {{#Bidirectional}}<{{/Bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}--> {{{innerNodeName}}} : {{{label}}}
       {{/bothVisible}}
     {{/isList}}
   {{/DumpRelations}}
-  {{^Invisible}}
+  {{^invisible}}
     {{#InvisiblePath}}
       {{#InnerDumpNodes}}
 {{{outerNodeName}}} o.. {{{innerNodeName}}}
       {{/InnerDumpNodes}}
     {{/InvisiblePath}}
-  {{/Invisible}}
+  {{/invisible}}
   {{#PrintConfig}}{{#orderChildren}}
       {{#myChildren}}
           {{#hasSuccessor}}
@@ -71,13 +71,13 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{#backgroundColor}}#{{{backgroun
       {{/myChildren}}
   {{/orderChildren}}{{/PrintConfig}}
 {{/DumpNodes}}
-{{#BuildConfig}}
-  {{#Debug}}
+{{#PrintConfig}}
+  {{#debug}}
 legend right
   %date()
   dumpAst: {{{version}}}
   plantuml: %version()
 endlegend
-  {{/Debug}}
-{{/BuildConfig}}
+  {{/debug}}
+{{/PrintConfig}}
 @enduml
diff --git a/dumpAst/src/main/resources/dumpAstVersion.properties b/dumpAst/src/main/resources/dumpAstVersion.properties
index e0a9ca936f23641719ffee3bfed385ca97d946b8..b5884b7f4020f8cbe6c1bde27f8ad3d40af3215b 100644
--- a/dumpAst/src/main/resources/dumpAstVersion.properties
+++ b/dumpAst/src/main/resources/dumpAstVersion.properties
@@ -1,2 +1,2 @@
-#Thu Feb 24 09:45:15 CET 2022
-version=0.3.6
+#Tue Mar 01 11:14:25 CET 2022
+version=0.4.0
diff --git a/dumpAstWithPlantuml/.gitignore b/dumpAstWithPlantuml/.gitignore
deleted file mode 100644
index 87b4cdd3d7c6a41502ca98703abeeb69a1d536fb..0000000000000000000000000000000000000000
--- a/dumpAstWithPlantuml/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-build
-src/gen-res/
-src/gen/
-out/
-*.class
diff --git a/dumpAstWithPlantuml/build.gradle b/dumpAstWithPlantuml/build.gradle
deleted file mode 100644
index 03e3324a59b067b1c8f45dc1f7b44975194b779e..0000000000000000000000000000000000000000
--- a/dumpAstWithPlantuml/build.gradle
+++ /dev/null
@@ -1,99 +0,0 @@
-buildscript {
-    repositories.mavenLocal()
-    repositories.mavenCentral()
-    dependencies {
-        classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3'
-    }
-}
-
-plugins {
-    id 'relast2uml.java-jastadd-conventions'
-    id 'relast2uml.java-publishing-conventions'
-}
-
-apply plugin: 'jastadd'
-
-dependencies {
-    implementation fileTree(include: ['plantuml.jar'], dir: '../libs')
-
-    implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "${mustache_java_version}"
-}
-
-File dumpAstGrammar = file('../dumpAst/src/main/jastadd/DumpAst.relast')
-
-task relast(type: JavaExec) {
-    group = 'Build'
-    main = "-jar"
-
-    doFirst {
-        delete "src/gen/jastadd/*.ast"
-        delete "src/gen/jastadd/DumpAst.jadd"
-        delete "src/gen/jastadd/DumpAstRefResolver.jadd"
-        delete "src/gen/jastadd/DumpAstResolverStubs.jrag"
-        mkdir  "src/gen/jastadd/"
-    }
-
-    args = [
-            "../libs/relast.jar",
-            dumpAstGrammar,
-//            "./src/main/jastadd/MustacheNodes.relast",
-            "--listClass=java.util.ArrayList",
-            "--jastAddList=JastAddList",
-            "--useJastAddNames",
-            "--file",
-            "--resolverHelper",
-            "--grammarName=./src/gen/jastadd/DumpAst"
-    ]
-
-    inputs.files(file("../libs/relast.jar"),
-            dumpAstGrammar)
-    outputs.files(file("./src/gen/jastadd/DumpAst.ast"),
-            file("./src/gen/jastadd/DumpAst.jadd"),
-            file("./src/gen/jastadd/DumpAstRefResolver.jadd"),
-            file('./src/gen/jastadd/DumpAstResolverStubs.jrag'))
-}
-
-jastadd {
-    configureModuleBuild()
-    modules {
-        //noinspection GroovyAssignabilityCheck
-        module("DumpAstWithPlantuml") {
-
-            java {
-                basedir "."
-                include "src/main/**/*.java"
-                include "src/gen/**/*.java"
-            }
-
-            jastadd {
-                basedir ".."
-                include "dumpAst/src/main/jastadd/**/*.ast"
-                include "dumpAst/src/main/jastadd/**/*.jadd"
-                include "dumpAst/src/main/jastadd/**/*.jrag"
-                include "dumpAstWithPlantuml/src/main/jastadd/**/*.jadd"
-                include "dumpAst/src/gen/jastadd/**/*.ast"
-                include "dumpAst/src/gen/jastadd/**/*.jadd"
-                include "dumpAst/src/gen/jastadd/**/*.jrag"
-            }
-        }
-    }
-
-    cleanGen.doFirst {
-        delete "src/gen/java/de"
-        delete "src/gen-res/BuildInfo.properties"
-    }
-
-    preprocessParser.doFirst {
-
-        args += ["--no-beaver-symbol"]
-
-    }
-
-    module = "DumpAstWithPlantuml"
-    astPackage = 'de.tudresden.inf.st.jastadd.dumpAst.ast'
-    genDir = 'src/gen/java'
-    buildInfoDir = 'src/gen-res'
-    jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
-}
-
-generateAst.dependsOn relast
diff --git a/dumpAstWithPlantuml/src/main/jastadd/Generation.jadd b/dumpAstWithPlantuml/src/main/jastadd/Generation.jadd
deleted file mode 100644
index 35905af0dc789adfc17971ed23ede287db032d52..0000000000000000000000000000000000000000
--- a/dumpAstWithPlantuml/src/main/jastadd/Generation.jadd
+++ /dev/null
@@ -1,29 +0,0 @@
-aspect Generation {
-
-    /**
-     * Write out content as PNG image generated by plantuml.
-     * @param destination path of destination file
-     * @return this
-     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
-     */
-    public DumpBuilder DumpBuilder.dumpAsPNG(java.nio.file.Path destination) throws java.io.IOException {
-      String content = build().toPlantUml();
-      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
-      reader.outputImage(java.nio.file.Files.newOutputStream(destination));
-      return this;
-    }
-
-    /**
-     * Write out content as SVG image generated by plantuml.
-     * @param destination path of destination file
-     * @return this
-     * @throws java.io.IOException if an I/O error happend during opening or writing in that file
-     */
-    public DumpBuilder DumpBuilder.dumpAsSVG(java.nio.file.Path destination) throws java.io.IOException {
-      String content = build().toPlantUml();
-      net.sourceforge.plantuml.SourceStringReader reader = new net.sourceforge.plantuml.SourceStringReader(content);
-      reader.outputImage(java.nio.file.Files.newOutputStream(destination),
-          new net.sourceforge.plantuml.FileFormatOption(net.sourceforge.plantuml.FileFormat.SVG));
-      return this;
-    }
-}
\ No newline at end of file
diff --git a/dumpAstWithPlantuml/src/main/resources/dumpAst.mustache b/dumpAstWithPlantuml/src/main/resources/dumpAst.mustache
deleted file mode 120000
index e549bf371db8fa4554a0b276e52a3c5b978af0a3..0000000000000000000000000000000000000000
--- a/dumpAstWithPlantuml/src/main/resources/dumpAst.mustache
+++ /dev/null
@@ -1 +0,0 @@
-../../../../dumpAst/src/main/resources/dumpAst.mustache
\ No newline at end of file
diff --git a/dumpAstWithPlantuml/src/main/resources/dumpAstWithPlantumlVersion.properties b/dumpAstWithPlantuml/src/main/resources/dumpAstWithPlantumlVersion.properties
deleted file mode 120000
index 19186b38f76bfc2fb8f855e0c5bafe020db4bae4..0000000000000000000000000000000000000000
--- a/dumpAstWithPlantuml/src/main/resources/dumpAstWithPlantumlVersion.properties
+++ /dev/null
@@ -1 +0,0 @@
-../../../../dumpAst/src/main/resources/dumpAstVersion.properties
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 631fcc974ebb903bd09ad6b13cd6dd5fbd875f3d..c0cb5215b2f3dce2dc608c5052ce71d39aeffac6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,5 +2,4 @@ rootProject.name = 'relast2uml'
 
 include 'relast.preprocessor'
 include 'dumpAst'
-include 'dumpAstWithPlantuml'
 include 'testDumper'
diff --git a/testDumper/build.gradle b/testDumper/build.gradle
index 1c0603dc55c06e22ddea0a727ea178102ece369a..51757d93e7ca60995ec97eba1d3fa7dce3c1dcea 100644
--- a/testDumper/build.gradle
+++ b/testDumper/build.gradle
@@ -8,14 +8,19 @@ buildscript {
 
 plugins {
     id 'relast2uml.java-jastadd-conventions'
+    id 'relast2uml.java-application-conventions'
 }
 
 apply plugin: 'jastadd'
 
 dependencies {
-    testImplementation project(':dumpAst')
+    implementation project(':dumpAst')
+// https://mvnrepository.com/artifact/org.slf4j/slf4j-simple
+    implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.36'
 }
 
+mainClassName = 'de.tudresden.inf.st.jastadd.testDumper.TestDumperMain'
+
 File testingGrammar = file('./src/main/jastadd/testDumper.relast')
 
 task relast(type: JavaExec) {
diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java b/testDumper/src/main/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java
similarity index 66%
rename from testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java
rename to testDumper/src/main/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java
index a031f27abe944729ff46aee2c4e021af8efacaf1..300d62e4429c77ded3f52832d7754b42cf98882d 100644
--- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java
+++ b/testDumper/src/main/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java
@@ -1,6 +1,7 @@
 package de.tudresden.inf.st.jastadd.testDumper;
 
 import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst;
+import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpBuilder;
 import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpListChildNode;
 import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
 import org.jastadd.testDumper.ast.A;
@@ -8,14 +9,46 @@ import org.jastadd.testDumper.ast.B;
 import org.jastadd.testDumper.ast.C;
 import org.jastadd.testDumper.ast.Root;
 
-import java.util.Arrays;
-import java.util.List;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+@SuppressWarnings({"unused", "CommentedOutCode"})
 public class TestDumperMain {
-  public static void main(String[] args) {
-    Root root = new Root();
+  private Root root;
+  private DumpAst dumpAst;
+
+  public static void main(String[] args) throws IOException {
+    new TestDumperMain().run();
+  }
+
+  void run() throws IOException {
+    createRoot();
+
+    ExposingDumpBuilder builder = new ExposingDumpBuilder(root);
+    String preamble = "{<\n>\n}";
+    builder.includeAttributes("simpleAttr")
+        .orderChildren()
+        .includeNonterminalAttributes("getCalculated")
+        .setNameMethod(n -> n == null ? "null" : n.getClass().getSimpleName())
+        .customPreamble(preamble);
+
+    System.out.println(">> PlantUml");
+    dumpAst = builder.build();
+    System.out.println(dumpAst.toPlantUml());
+
+    Path path = Paths.get("src/gen/resources/");
+    Files.createDirectories(path);
+    builder.dumpAsYaml(path.resolve("testDumperMain.yaml"), true);
+
+//    printAdditionalInformation();
+  }
+
+  private void createRoot() {
+    root = new Root();
     root.setName("Root1");
     A a = new A();
     a.setName("A2");
@@ -34,20 +67,9 @@ public class TestDumperMain {
     root.addB(b1);
     root.addB(b2);
     root.setC(c);
+  }
 
-    TestUtils.ExposingDumpBuilder builder = new TestUtils.ExposingDumpBuilder(root);
-    builder.includeAttributes("simpleAttr")
-        .orderChildren()
-        .includeNonterminalAttributes("getCalculated")
-        .setNameMethod(n -> n == null ? "null" : n.getClass().getSimpleName());
-
-    System.out.println(">> PlantUml");
-    DumpAst dumpAst = builder.build();
-    System.out.println(dumpAst.toPlantUml());
-
-    String[] b = new String[]{"1"};
-    List<String> l = Arrays.asList(b);
-
+  private void printAdditionalInformation() {
     DumpNode node = dumpAst.getDumpNode(0);
     System.out.println(node.getName());
     Function<? super DumpNode, String> printInfo = d ->
@@ -72,4 +94,17 @@ public class TestDumperMain {
 //    System.out.println(builder.build().toYaml(true));
 //    System.out.println(">> YAML end");
   }
+
+  static class ExposingDumpBuilder extends DumpBuilder {
+
+    protected ExposingDumpBuilder(Object target) {
+      super(target);
+    }
+
+    @Override
+    public DumpAst build() {
+      return super.build();
+    }
+  }
+
 }
diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java
index 0e6a927baafd60e60f09e9368308776f602ebc80..1b9be71cc6a27b381a94127d8cab991f06a87479 100644
--- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java
+++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java
@@ -6,6 +6,10 @@ import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
 import org.jastadd.testDumper.ast.*;
 import org.junit.jupiter.api.Test;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.List;
 import java.util.Optional;
 
@@ -28,11 +32,16 @@ public class TestSimple {
   }
 
   @Test
-  public void testCustomPreamble() {
+  public void testCustomPreamble() throws IOException {
     Root root = createRoot(null, null);
     String preamble = "{<\n>\n}";
     ExposingDumpBuilder builder = new ExposingDumpBuilder(root);
     builder.excludeNullNodes().customPreamble(preamble);
+
+    Path path = Paths.get("src/gen/resources/");
+    Files.createDirectories(path);
+    builder.dumpAsYaml(path.resolve("customPreamble.yaml"), true);
+
     DumpAst dumpAst = builder.build();
     String puml = dumpAst.toPlantUml();
     assertThat(puml).contains(preamble);
diff --git a/testDumper/src/test/resources/simplelogger.properties b/testDumper/src/test/resources/simplelogger.properties
new file mode 100644
index 0000000000000000000000000000000000000000..beb56b2e15b78fb9a777c5c449bcae65621938db
--- /dev/null
+++ b/testDumper/src/test/resources/simplelogger.properties
@@ -0,0 +1 @@
+org.slf4j.simpleLogger.defaultLogLevel=debug