diff --git a/dumpAst/src/main/jastadd/DumpAst.relast b/dumpAst/src/main/jastadd/DumpAst.relast
index 13d438ede1180d96e49a780b817e5db0ffff3050..7a3e31f2cfc389af9e9cd14228697b59c5929dc1 100644
--- a/dumpAst/src/main/jastadd/DumpAst.relast
+++ b/dumpAst/src/main/jastadd/DumpAst.relast
@@ -1,7 +1,9 @@
 DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ;
 rel DumpAst.RootNode -> DumpNode ;
 
-BuildConfig ::= <TypeIgnore> <TokenIgnore> <ChildIgnore> <AttributeInclude> <NonterminalAttributeInclude> <RelationIgnore> <IncludeEmptyString:boolean> <Debug:boolean> ;
+BuildConfig ::= GlobalPatternCollection:PatternCollection ExcludeTypePattern:TypePatternCollectionMapping* IncludeTypePattern:TypePatternCollectionMapping* <TypeIgnorePattern> <IncludeEmptyString:boolean> <Debug:boolean> ;
+TypePatternCollectionMapping ::= <TypeRegex> PatternCollection ;
+PatternCollection ::= <TokenPattern> <ChildPattern> <RelationPattern> <AttributePattern> <NonterminalAttributePattern> ;
 PrintConfig ::= <Scale:double> <Version> Header* ;
 Header ::= <Value> ;
 DumpNode ::= <Name> <Label> <Object:Object> <Invisible:boolean> DumpChildNode* DumpToken* DumpRelation* /InvisiblePath/ ;
diff --git a/dumpAst/src/main/jastadd/Generation.jadd b/dumpAst/src/main/jastadd/GenerationBackend.jadd
similarity index 66%
rename from dumpAst/src/main/jastadd/Generation.jadd
rename to dumpAst/src/main/jastadd/GenerationBackend.jadd
index d6a2a37f358923affb9fae608adc8dc8ea96b5dc..c59d1cc444f46b65ba76f6e9161138ee1f991780 100644
--- a/dumpAst/src/main/jastadd/Generation.jadd
+++ b/dumpAst/src/main/jastadd/GenerationBackend.jadd
@@ -1,211 +1,3 @@
-import java.lang.String;aspect GenerationFrontend {
-  public class Dumper {
-    /**
-     * Prepare to read in the given object. Use the <code>dump*</code> methods to actually dump its content.
-     * @param obj the object to dump
-     * @return a builder to adjust dump options
-     */
-    public static DumpBuilder read(Object obj) {
-      return new DumpBuilder(obj);
-    }
-  }
-  public enum SkinParamBooleanSetting {
-    /** Print in grayscale? */
-    Monochrome,
-    /** Use shadows? */
-    Shadowing,
-    /** Use handwritten style? */
-    Handwritten
-  }
-  public enum SkinParamStringSetting {
-    /** Set color of background */
-    backgroundColor
-  }
-  public class DumpBuilder {
-    private Object target;
-    private String packageName;
-    private DumpAst result;
-    private BuildConfig buildConfig = new BuildConfig();
-    private PrintConfig printConfig = new PrintConfig();
-
-    protected DumpBuilder(Object target) {
-      this.target = target;
-      printConfig.setScale(1);
-      printConfig.setVersion(readVersion());
-    }
-
-    /**
-     * Add debug information in dumped content, mainly version numbers.
-     * @return this
-     */
-    public DumpBuilder enableDebug() {
-      buildConfig.setDebug(true);
-      return this;
-    }
-
-    /**
-     * Include empty strings for all tokens
-     * @return this
-     */
-    public DumpBuilder includeEmptyStringsOnTokens() {
-      buildConfig.setIncludeEmptyString(true);
-      return this;
-    }
-
-    /**
-     * Disable all objects with types matching at least one of the given regex strings.
-     * Disabled objects won't be included in any output. However, their children are still processed.
-     * @param regexes patterns to match type names
-     * @return this
-     * @see java.util.regex.Pattern#compile(java.lang.String)
-     */
-    public DumpBuilder disableTypes(String... regexes) {
-      updateRegexes(() -> buildConfig.getTypeIgnore(), s -> buildConfig.setTypeIgnore(s), regexes);
-      return this;
-    }
-
-    /**
-     * Exclude tokens and their value if the token name matches at least one of the given regex strings.
-     * @param regexes regex patterns to match token names
-     * @return this
-     * @see java.util.regex.Pattern#compile(java.lang.String)
-     */
-    public DumpBuilder excludeTokens(String... regexes) {
-      updateRegexes(() -> buildConfig.getTokenIgnore(), s -> buildConfig.setTokenIgnore(s), regexes);
-      return this;
-    }
-
-    /**
-     * Include attributes (as tokens) and their value if the attribute name matches at least on of the given regex strings.
-     * @param regexes regex patterns to match token names
-     * @return this
-     * @see java.util.regex.Pattern#compile(java.lang.String)
-     */
-    public DumpBuilder includeAttributes(String... regexes) {
-      updateRegexes(() -> buildConfig.getAttributeInclude(), s -> buildConfig.setAttributeInclude(s), regexes);
-      return this;
-    }
-
-    /**
-     * Includes nonterminal-attributes (as children) and their values if
-     * their attribute name matches at least on of the given regex strings.
-     * <br>
-     * <b>Note</b>: A leading "get" and a trailing "List" in the name will be removed prior to matching.
-     * Thus, it should not be contained in the regex either.
-     * @param regexes regex patterns to match token names
-     * @return this
-     * @see java.util.regex.Pattern#compile(java.lang.String)
-     */
-    public DumpBuilder includeNonterminalAttributes(String... regexes) {
-      updateRegexes(() -> buildConfig.getNonterminalAttributeInclude(), s -> buildConfig.setNonterminalAttributeInclude(s), regexes);
-      return this;
-    }
-
-    /**
-     * Exclude every child whose name (i.e., context) matches at least on of the given regex strings.
-     * This means, that the complete object and its (transitive) children will never be included in any output.
-     * @param regexes regex patterns to match child names
-     * @return this
-     * @see java.util.regex.Pattern#compile(java.lang.String)
-     */
-    public DumpBuilder excludeChildren(String... regexes) {
-      updateRegexes(() -> buildConfig.getChildIgnore(), s -> buildConfig.setChildIgnore(s), regexes);
-      return this;
-    }
-    /**
-     * Exclude every relation whose role-name matches at least on of the given regex strings.
-     * This means two things: a) the relation to any potential target object(s) is never shown, and b) the target
-     *  object(s) are not shown unless they are reachable by another relation or by containment.
-     * @param regexes regex patterns to match child names
-     * @return this
-     * @see java.util.regex.Pattern#compile(java.lang.String)
-     */
-    public DumpBuilder excludeRelations(String... regexes) {
-      updateRegexes(() -> buildConfig.getRelationIgnore(), s -> buildConfig.setRelationIgnore(s), regexes);
-      return this;
-    }
-
-    private void updateRegexes(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String... values) {
-      for (String value : values) {
-        if (getter.get().isEmpty()) {
-          setter.accept(value);
-        } else {
-          setter.accept(getter.get() + "|" + value);
-        }
-      }
-    }
-
-    public DumpBuilder customPreamble(String option) {
-      printConfig.addHeader(new Header(option));
-      return this;
-    }
-
-    public DumpBuilder skinParam(SkinParamStringSetting setting, String value) {
-      customPreamble("skinparam " + setting.toString() + " " + value);
-      return this;
-    }
-    public DumpBuilder skinParam(SkinParamBooleanSetting setting, boolean value) {
-      customPreamble("skinparam " + setting.toString() + " " + value);
-      return this;
-    }
-
-    public DumpBuilder setScale(double value) {
-      printConfig.setScale(value);
-      return this;
-    }
-
-    private String readVersion() {
-      try {
-        java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion");
-        return resources.getString("version");
-      } catch (java.util.MissingResourceException e) {
-        return "version ?";
-      }
-    }
-
-    protected DumpAst build() {
-      if (result == null) {
-        result = new DumpAst();
-        result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName);
-        result.setBuildConfig(this.buildConfig);
-        result.setPrintConfig(this.printConfig);
-        try {
-          result.transform(new TransformationTransferInformation(), this.target);
-        } catch (java.lang.reflect.InvocationTargetException e) {
-          throw new RuntimeException("Could not transform :(", e);
-        } catch (IllegalAccessException e) {
-          throw new RuntimeException("Could not transform :(", e);
-        } catch (NoSuchMethodException e) {
-          throw new RuntimeException("Could not transform :(", e);
-        }
-      }
-      return result;
-    }
-
-    /**
-     * Write out content as plantuml source code.
-     * @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 dumpAsSource(java.nio.file.Path destination) throws java.io.IOException {
-      String content = build().toPlantUml();
-      try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
-        writer.write(content);
-      }
-      return this;
-    }
-
-    public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException {
-      String content = build().toYaml(prependCreationComment);
-      try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
-        writer.write(content);
-      }
-      return this;
-    }
-  }
-}
-
 aspect GenerationBackend {
   class DumpAst {
     private enum Source {
@@ -238,6 +30,7 @@ aspect GenerationBackend {
       return null;
     }
     DumpNode node = tti.transformed.get(obj);
+    String objClassName = obj.getClass().getSimpleName();
     if (node != null) {
       if (source == Source.RELATION) {
         return node;
@@ -247,7 +40,7 @@ aspect GenerationBackend {
     } else {
       node = new DumpNode();
       node.setObject(obj);
-      node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode());
+      node.setLabel(objClassName + "@" + obj.hashCode());
       node.setName("node" + tti.transformed.size());
       tti.transformed.put(obj, node);
       this.addDumpNode(node);
@@ -258,7 +51,7 @@ aspect GenerationBackend {
         tti.relationTargetsUnprocessed.put(node, true);
         return node;
       }
-      if (source == Source.INVISIBLE_PARENT || matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) {
+      if (source == Source.INVISIBLE_PARENT || !isTypeEnabled(objClassName)) {
         node.setInvisible(true);
       }
       final ClassAnalysisResult car = analyzeClass(obj.getClass());
@@ -266,7 +59,7 @@ aspect GenerationBackend {
       for (SingleChildMethod singleChildMethod : car.singleChildMethods()) {
         Object target = singleChildMethod.getMethod().invoke(obj);
         String childName = singleChildMethod.getName();
-        DumpNode targetNode = transform(tti, target, nextSource(source, matches(getBuildConfig().childIgnorePattern(), childName)));
+        DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)));
         if (target != null && targetNode != null) {
           DumpNormalChildNode normalChild = new DumpNormalChildNode();
           normalChild.setName(childName);
@@ -281,7 +74,7 @@ aspect GenerationBackend {
         DumpListChildNode listChild = new DumpListChildNode();
         listChild.setComputed(listChildMethod.isNTAListChildMethod());
         String childName = listChildMethod.getName();
-        boolean shouldBeInvisisble = matches(getBuildConfig().childIgnorePattern(), childName);
+        boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName);
         listChild.setName(childName);
         for (Object target : targetList) {
           DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble));
@@ -354,6 +147,7 @@ aspect GenerationBackend {
 
   syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) {
     ClassAnalysisResult result = new ClassAnalysisResult();
+    String clazzName = clazz.getSimpleName();
     for (java.lang.reflect.Method method : clazz.getMethods()) {
       for (java.lang.annotation.Annotation annotation : method.getAnnotations()) {
         String canonicalName = annotation.annotationType().getCanonicalName();
@@ -377,7 +171,7 @@ aspect GenerationBackend {
                 normalSingleChildMethod.setName(optChildName);
                 result.addAnalysedMethod(normalSingleChildMethod);
               } catch (NoSuchMethodException e) {
-                System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazz.getName());
+                System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazzName);
                 throw new RuntimeException(e);
               }
               break;
@@ -396,7 +190,7 @@ aspect GenerationBackend {
                 try {
                   java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName);
                   // normal get + token-name -> singleRelation
-                  if (!matches(getBuildConfig().relationIgnorePattern(), relationName)) {
+                  if (isRelationEnabled(clazzName, relationName)) {
                     SingleRelationMethod singleRelationMethod = new SingleRelationMethod();
                     singleRelationMethod.setMethod(relationMethod);
                     singleRelationMethod.setName(relationName);
@@ -410,7 +204,7 @@ aspect GenerationBackend {
                 try {
                   java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName + "List");
                   // normal get + token-name + "List" -> listRelation
-                  if (!matches(getBuildConfig().relationIgnorePattern(), relationName)) {
+                  if (isRelationEnabled(clazzName, relationName)) {
                     ListRelationMethod listRelationMethod = new ListRelationMethod();
                     listRelationMethod.setMethod(relationMethod);
                     listRelationMethod.setName(relationName);
@@ -421,7 +215,7 @@ aspect GenerationBackend {
                   // ignore, but we know this is probably not a relation at all
                 }
               }
-              if (!matches(getBuildConfig().tokenIgnorePattern(), tokenName)) {
+              if (isTokenEnabled(clazzName, tokenName)) {
                 IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod();
                 tokenMethod.setMethod(method);
                 tokenMethod.setName(tokenName);
@@ -440,7 +234,7 @@ aspect GenerationBackend {
                 if (attributeName.endsWith("List")) {
                   attributeName = attributeName.substring(0, attributeName.length() - 4);
                 }
-                if (matches(getBuildConfig().ntaIncludePattern(), attributeName)) {
+                if (isNonterminalAttributeEnabled(clazzName, attributeName)) {
                   if (Iterable.class.isAssignableFrom(method.getReturnType())) {
                     NTAListChildMethod ntaListChildMethod = new NTAListChildMethod();
                     ntaListChildMethod.setMethod(method);
@@ -453,7 +247,7 @@ aspect GenerationBackend {
                     result.addAnalysedMethod(ntaSingleChildMethod);
                   }
                 }
-              } else if (matches(getBuildConfig().attributeIncludePattern(), attributeName)) {
+              } else if (isAttributeEnabled(clazzName, attributeName)) {
                 // normal attribute
                 AttributeMethod attributeMethod = new AttributeMethod();
                 attributeMethod.setMethod(method);
@@ -475,12 +269,32 @@ aspect GenerationBackend {
     return Character.toUpperCase(s.charAt(0)) + s.substring(1);
   }
 
-  syn java.util.regex.Pattern BuildConfig.typeIgnorePattern() = java.util.regex.Pattern.compile(getTypeIgnore());
-  syn java.util.regex.Pattern BuildConfig.childIgnorePattern() = java.util.regex.Pattern.compile(getChildIgnore());
-  syn java.util.regex.Pattern BuildConfig.tokenIgnorePattern() = java.util.regex.Pattern.compile(getTokenIgnore());
-  syn java.util.regex.Pattern BuildConfig.attributeIncludePattern() = java.util.regex.Pattern.compile(getAttributeInclude());
-  syn java.util.regex.Pattern BuildConfig.ntaIncludePattern() = java.util.regex.Pattern.compile(getNonterminalAttributeInclude());
-  syn java.util.regex.Pattern BuildConfig.relationIgnorePattern() = java.util.regex.Pattern.compile(getRelationIgnore());
+  // TODO: add new attributes for: {token,child,relation,attribute,nta}Enabled(String parentType, String name). 1) just move implementation into this attribute. 2) add include/exclude on type-level to it.
+  syn boolean DumpAst.isTypeEnabled(String typeName) {
+    return !matches(getBuildConfig().typeIgnorePattern(), typeName);
+  }
+  syn boolean DumpAst.isTokenEnabled(String parentType, String tokenName) {
+    return !matches(getBuildConfig().getGlobalPatternCollection().tokenIgnorePattern(), tokenName);
+  }
+  syn boolean DumpAst.isChildEnabled(String parentType, String childName) {
+    return !matches(getBuildConfig().getGlobalPatternCollection().childIgnorePattern(), childName);
+  }
+  syn boolean DumpAst.isRelationEnabled(String parentType, String relationName) {
+    return !matches(getBuildConfig().getGlobalPatternCollection().relationIgnorePattern(), relationName);
+  }
+  syn boolean DumpAst.isAttributeEnabled(String parentType, String attributeName) {
+    return matches(getBuildConfig().getGlobalPatternCollection().attributeIncludePattern(), attributeName);
+  }
+  syn boolean DumpAst.isNonterminalAttributeEnabled(String parentType, String ntaName) {
+    return matches(getBuildConfig().getGlobalPatternCollection().ntaIncludePattern(), ntaName);
+  }
+
+  syn java.util.regex.Pattern BuildConfig.typeIgnorePattern() = java.util.regex.Pattern.compile(getTypeIgnorePattern());
+  syn java.util.regex.Pattern PatternCollection.childIgnorePattern() = java.util.regex.Pattern.compile(getChildPattern());
+  syn java.util.regex.Pattern PatternCollection.tokenIgnorePattern() = java.util.regex.Pattern.compile(getTokenPattern());
+  syn java.util.regex.Pattern PatternCollection.attributeIncludePattern() = java.util.regex.Pattern.compile(getAttributePattern());
+  syn java.util.regex.Pattern PatternCollection.ntaIncludePattern() = java.util.regex.Pattern.compile(getNonterminalAttributePattern());
+  syn java.util.regex.Pattern PatternCollection.relationIgnorePattern() = java.util.regex.Pattern.compile(getRelationPattern());
   static boolean ASTNode.matches(java.util.regex.Pattern p, String input) {
     return p.matcher(input).matches();
   }
diff --git a/dumpAst/src/main/jastadd/GenerationFrontend.jadd b/dumpAst/src/main/jastadd/GenerationFrontend.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..b6815cef840deb549085fdb2ce28f94f5f2758f6
--- /dev/null
+++ b/dumpAst/src/main/jastadd/GenerationFrontend.jadd
@@ -0,0 +1,314 @@
+aspect GenerationFrontend {
+  public class Dumper {
+    /**
+     * Prepare to read in the given object. Use the <code>dump*</code> methods to actually dump its content.
+     * @param obj the object to dump
+     * @return a builder to adjust dump options
+     */
+    public static DumpBuilder read(Object obj) {
+      return new DumpBuilder(obj);
+    }
+  }
+  public enum SkinParamBooleanSetting {
+    /** Print in grayscale? */
+    Monochrome,
+    /** Use shadows? */
+    Shadowing,
+    /** Use handwritten style? */
+    Handwritten
+  }
+  public enum SkinParamStringSetting {
+    /** Set color of background */
+    backgroundColor
+  }
+
+/**
+ * Building a dump.
+ * <p>
+ *
+ * <h3>Inclusion and Exclusion of Types</h3>
+ * Types can be only be disabled, see {@link #disableTypes(String[])}.
+ *
+ * <h3>Inclusion and Exclusion of Childrens, tokens and relations</h3>
+ * Childrens, tokens and relations are included by default.
+ * This can be changed using exclusions and inclusion, both in general and per-type.
+ * They are applied in the following order making later conditions take precedence over the first ones.
+ * <ol>
+ *   <li>Include everything as default.
+ *   <li>Exclude general.
+ *   <li>Include per type.
+ *   <li>Exclude per type.
+ * </ol>
+ *
+ * <h3>Inclusion and Exclusion of Attributes</h3>
+ * Attributes are excluded by default, i.e., not shown.
+ * This can be changed using inclusions and exclusions, both in general and per-type.
+ * They are applied in the following order making later conditions take precedence over the first ones.
+ * <ol>
+ *   <li> Exclude everything as default.
+ *   <li> Include general.
+ *   <li> Exclude per type.
+ *   <li> Include per type
+ * </ol>
+ */
+public class DumpBuilder {
+    private final Object target;
+    private String packageName;
+    private DumpAst result;
+    private final BuildConfig buildConfig;
+    private final PrintConfig printConfig;
+
+    protected DumpBuilder(Object target) {
+      this.target = target;
+      buildConfig = new BuildConfig();
+      buildConfig.setGlobalPatternCollection(new PatternCollection());
+      printConfig = new PrintConfig();
+      printConfig.setScale(1);
+      printConfig.setVersion(readVersion());
+    }
+
+    /**
+     * Add debug information in dumped content, mainly version numbers.
+     * @return this
+     */
+    public DumpBuilder enableDebug() {
+      buildConfig.setDebug(true);
+      return this;
+    }
+
+    /**
+     * Include empty strings for all tokens
+     * @return this
+     */
+    public DumpBuilder includeEmptyStringsOnTokens() {
+      buildConfig.setIncludeEmptyString(true);
+      return this;
+    }
+
+    /**
+     * Disable all objects with types matching at least one of the given regex strings.
+     * Disabled objects won't be included in any output. However, their children are still processed.
+     * <p>
+     * See {@link DumpBuilder} for details on inclusion and exclusion precedence.
+     * @param regexes patterns to match type names
+     * @return this
+     * @see java.util.regex.Pattern#compile(java.lang.String)
+     */
+    public DumpBuilder disableTypes(String... regexes) {
+      updateRegexes(() -> buildConfig.getTypeIgnorePattern(),
+                    s -> buildConfig.setTypeIgnorePattern(s),
+                    regexes);
+      return this;
+    }
+
+    /**
+     * Exclude tokens and their value if the token name matches at least one of the given regex strings.
+     * <p>
+     * See {@link DumpBuilder} for details on inclusion and exclusion precedence.
+     * @param regexes regex patterns to match token names
+     * @return this
+     * @see java.util.regex.Pattern#compile(java.lang.String)
+     */
+    public DumpBuilder excludeTokens(String... regexes) {
+      updateRegexes(() -> buildConfig.getGlobalPatternCollection().getTokenPattern(),
+                    s -> buildConfig.getGlobalPatternCollection().setTokenPattern(s),
+                    regexes);
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder excludeTokensFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder excludeChildrenFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder excludeRelationsFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder excludeAttributesFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder excludeNonterminalAttributesFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder includeTokensFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder includeChildrenFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder includeRelationsFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder includeAttributesFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /** TODO: document, implement, sort */
+    public DumpBuilder includeNonterminalAttributesFor(String typeRegex, String... regexes) {
+      return this;
+    }
+
+    /**
+     * Include attributes (as tokens) and their value if the attribute name matches at least on of the given regex strings.
+     * <p>
+     * See {@link DumpBuilder} for details on inclusion and exclusion precedence.
+     * @param regexes regex patterns to match token names
+     * @return this
+     * @see java.util.regex.Pattern#compile(java.lang.String)
+     */
+    public DumpBuilder includeAttributes(String... regexes) {
+      updateRegexes(() -> buildConfig.getGlobalPatternCollection().getAttributePattern(),
+                    s -> buildConfig.getGlobalPatternCollection().setAttributePattern(s),
+                    regexes);
+      return this;
+    }
+
+    /**
+     * Includes nonterminal-attributes (as children) and their values if
+     * their attribute name matches at least on of the given regex strings.
+     * <br>
+     * <b>Note</b>: A leading "get" and a trailing "List" in the name will be removed prior to matching.
+     * Thus, it should not be contained in the regex either.
+     * <p>
+     * See {@link DumpBuilder} for details on inclusion and exclusion precedence.
+     * @param regexes regex patterns to match token names
+     * @return this
+     * @see java.util.regex.Pattern#compile(java.lang.String)
+     */
+    public DumpBuilder includeNonterminalAttributes(String... regexes) {
+      updateRegexes(() -> buildConfig.getGlobalPatternCollection().getNonterminalAttributePattern(),
+                    s -> buildConfig.getGlobalPatternCollection().setNonterminalAttributePattern(s),
+                    regexes);
+      return this;
+    }
+
+    /**
+     * Exclude every child whose name (i.e., context) matches at least on of the given regex strings.
+     * This means, that the complete object and its (transitive) children will never be included in any output.
+     * <p>
+     * See {@link DumpBuilder} for details on inclusion and exclusion precedence.
+     * @param regexes regex patterns to match child names
+     * @return this
+     * @see java.util.regex.Pattern#compile(java.lang.String)
+     */
+    public DumpBuilder excludeChildren(String... regexes) {
+      updateRegexes(() -> buildConfig.getGlobalPatternCollection().getChildPattern(),
+                    s -> buildConfig.getGlobalPatternCollection().setChildPattern(s),
+                    regexes);
+      return this;
+    }
+    /**
+     * Exclude every relation whose role-name matches at least on of the given regex strings.
+     * This means two things: a) the relation to any potential target object(s) is never shown, and b) the target
+     *  object(s) are not shown unless they are reachable by another relation or by containment.
+     * <p>
+     * See {@link DumpBuilder} for details on inclusion and exclusion precedence.
+     * @param regexes regex patterns to match child names
+     * @return this
+     * @see java.util.regex.Pattern#compile(java.lang.String)
+     */
+    public DumpBuilder excludeRelations(String... regexes) {
+      updateRegexes(() -> buildConfig.getGlobalPatternCollection().getRelationPattern(),
+                    s -> buildConfig.getGlobalPatternCollection().setRelationPattern(s),
+                    regexes);
+      return this;
+    }
+
+    private void updateRegexes(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String... values) {
+      for (String value : values) {
+        if (getter.get().isEmpty()) {
+          setter.accept(value);
+        } else {
+          setter.accept(getter.get() + "|" + value);
+        }
+      }
+    }
+
+    public DumpBuilder customPreamble(String option) {
+      printConfig.addHeader(new Header(option));
+      return this;
+    }
+
+    public DumpBuilder skinParam(SkinParamStringSetting setting, String value) {
+      customPreamble("skinparam " + setting.toString() + " " + value);
+      return this;
+    }
+    public DumpBuilder skinParam(SkinParamBooleanSetting setting, boolean value) {
+      customPreamble("skinparam " + setting.toString() + " " + value);
+      return this;
+    }
+
+    public DumpBuilder setScale(double value) {
+      printConfig.setScale(value);
+      return this;
+    }
+
+    private String readVersion() {
+      try {
+        java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion");
+        return resources.getString("version");
+      } catch (java.util.MissingResourceException e) {
+        return "version ?";
+      }
+    }
+
+    protected DumpAst build() {
+      if (result == null) {
+        result = new DumpAst();
+        result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName);
+        result.setBuildConfig(this.buildConfig);
+        result.setPrintConfig(this.printConfig);
+        try {
+          result.transform(new TransformationTransferInformation(), this.target);
+        } catch (java.lang.reflect.InvocationTargetException e) {
+          throw new RuntimeException("Could not transform :(", e);
+        } catch (IllegalAccessException e) {
+          throw new RuntimeException("Could not transform :(", e);
+        } catch (NoSuchMethodException e) {
+          throw new RuntimeException("Could not transform :(", e);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * Write out content as plantuml source code.
+     * @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 dumpAsSource(java.nio.file.Path destination) throws java.io.IOException {
+      String content = build().toPlantUml();
+      try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
+        writer.write(content);
+      }
+      return this;
+    }
+
+    public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException {
+      String content = build().toYaml(prependCreationComment);
+      try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) {
+        writer.write(content);
+      }
+      return this;
+    }
+  }
+}
diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java
index fcb3b16d4378d64052ea88df14d63d755c988b70..5725e0db228d7e3b237172ecf7bd94936990eaf2 100644
--- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java
+++ b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java
@@ -55,7 +55,6 @@ public class Compiler extends AbstractCompiler {
   }
 
   public static void main(String[] args) {
-    System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
     System.setProperty("mustache.debug", "true");
     try {
       new Compiler().run(args);
@@ -96,7 +95,7 @@ public class Compiler extends AbstractCompiler {
         new BooleanOption("help", "Print usage and exit.")
         .defaultValue(false));
     optionVersion = addOption(
-        new BooleanOption("help", "Print version and exit.")
+        new BooleanOption("version", "Print version and exit.")
         .defaultValue(false));
     optionVerbose = addOption(
         new BooleanOption("verbose", "Print more messages while compiling.")