diff --git a/dumpAst/src/main/jastadd/DumpAst.relast b/dumpAst/src/main/jastadd/DumpAst.relast
index 730a4245e198b562ba06b1591c91dfe73285a3b3..c1b1ed92c553bcdf7950bec1f328e4e6fac9777b 100644
--- a/dumpAst/src/main/jastadd/DumpAst.relast
+++ b/dumpAst/src/main/jastadd/DumpAst.relast
@@ -1,5 +1,5 @@
 DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ;
-BuildConfig ::= <TypeIgnore> <TokenIgnore> <ChildIgnore> <AttributeIgnore> <RelationIgnore> <IncludeEmptyString:boolean> <Debug:boolean> ;
+BuildConfig ::= <TypeIgnore> <TokenIgnore> <ChildIgnore> <AttributeInclude> <NonterminalAttributeInclude> <RelationIgnore> <IncludeEmptyString:boolean> <Debug:boolean> ;
 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/Generation.jadd
index ee53e202e266792124b1ad83392e281e1d5533ab..c1d02452dc9af86de8f928f831b8d272681806f1 100644
--- a/dumpAst/src/main/jastadd/Generation.jadd
+++ b/dumpAst/src/main/jastadd/Generation.jadd
@@ -60,7 +60,7 @@ import java.lang.String;aspect GenerationFrontend {
      * @see java.util.regex.Pattern#compile(java.lang.String)
      */
     public DumpBuilder disableTypes(String... regexes) {
-      updateIgnored(() -> buildConfig.getTypeIgnore(), s -> buildConfig.setTypeIgnore(s), regexes);
+      updateRegexes(() -> buildConfig.getTypeIgnore(), s -> buildConfig.setTypeIgnore(s), regexes);
       return this;
     }
 
@@ -71,44 +71,45 @@ import java.lang.String;aspect GenerationFrontend {
      * @see java.util.regex.Pattern#compile(java.lang.String)
      */
     public DumpBuilder excludeTokens(String... regexes) {
-      updateIgnored(() -> buildConfig.getTokenIgnore(), s -> buildConfig.setTokenIgnore(s), regexes);
+      updateRegexes(() -> buildConfig.getTokenIgnore(), s -> buildConfig.setTokenIgnore(s), regexes);
       return this;
     }
     // not supported yet
     public DumpBuilder includeAttributes(String... regexes) {
-      updateIgnored(() -> buildConfig.getAttributeIgnore(), s -> buildConfig.setAttributeIgnore(s), regexes);
+      updateRegexes(() -> buildConfig.getAttributeInclude(), s -> buildConfig.setAttributeInclude(s), regexes);
       return this;
     }
     // not supported yet
     public DumpBuilder includeNonterminalAttributes(String... regexes) {
-      // TODO
+      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.
-     * Unlike disabling types, the complete object and its (transitive) children won't be included in any output.
+     * 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) {
-      updateIgnored(() -> buildConfig.getChildIgnore(), s -> buildConfig.setChildIgnore(s), 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.
-     * Unlike disabling types, the complete object and its (transitive) children won't be included in any output, except.
+     * 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) {
-      updateIgnored(() -> buildConfig.getRelationIgnore(), s -> buildConfig.setRelationIgnore(s), regexes);
+      updateRegexes(() -> buildConfig.getRelationIgnore(), s -> buildConfig.setRelationIgnore(s), regexes);
       return this;
     }
 
-    private void updateIgnored(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String... values) {
+    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);
@@ -209,28 +210,59 @@ import java.lang.String;aspect GenerationFrontend {
 }
 
 aspect GenerationBackend {
+  class DumpAst {
+    private enum Source {
+      RELATION, INVISIBLE_PARENT, PARENT, ROOT
+    }
+  }
+
   // --- transform --- (need to be a method, because it alters the AST while traversing the object structure)
-  // maybe return type is unncessary
   protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj)
       throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+    DumpNode result = transform(tti, obj, Source.ROOT);
+    // post-process relationTargetsUnprocessed
+    boolean someAreUnprocessed = true;
+    while (someAreUnprocessed) {
+      someAreUnprocessed = false;
+      java.util.Map<DumpNode, Boolean> copy = new java.util.HashMap<>(tti.relationTargetsUnprocessed);
+      for (java.util.Map.Entry<DumpNode, Boolean> entry : copy.entrySet()) {
+        if (entry.getValue()) {
+          transform(tti, entry.getKey().getObject(), Source.ROOT);
+          someAreUnprocessed = true;
+        }
+      }
+    }
+    return result;
+  }
+  protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj, Source source)
+      throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
     if (obj == null) {
       return null;
     }
-    if (tti.transformed.containsKey(obj)) {
-      return tti.transformed.get(obj);
-    }
-//      tti.transformed.put(obj, null);
-//      return null;
-    DumpNode node = new DumpNode();
-    node.setObject(obj);
-    node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode());
-    node.setName("node" + tti.transformed.size());
-    tti.transformed.put(obj, node);
-    this.addDumpNode(node);
-    if (matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) {
-      node.setInvisible(true);
+    DumpNode node = tti.transformed.get(obj);
+    if (node != null) {
+      if (source == Source.RELATION) {
+        return node;
+      }
+      // either processing as parent, or later as root-node. so mark it as processed.
+      tti.relationTargetsUnprocessed.put(node, false);
+    } else {
+      node = new DumpNode();
+      node.setObject(obj);
+      node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode());
+      node.setName("node" + tti.transformed.size());
+      tti.transformed.put(obj, node);
+      this.addDumpNode(node);
     }
     if (node.isAstNode()) {
+      // do not process node further if coming from a relation
+      if (source == Source.RELATION) {
+        tti.relationTargetsUnprocessed.put(node, true);
+        return node;
+      }
+      if (source == Source.INVISIBLE_PARENT || matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) {
+        node.setInvisible(true);
+      }
       // only caching node.analyseClass does not help, since we want to do this only once per class of a node
       final ClassAnalysisResult car;
       Class<?> clazz = obj.getClass();
@@ -243,10 +275,11 @@ aspect GenerationBackend {
       // -- singleChild --
       for (java.lang.reflect.Method method : car.singleChildMethods) {
         Object target = method.invoke(obj);
-        DumpNode targetNode = transform(tti, target);
+        String childName = car.names.get(method);
+        DumpNode targetNode = transform(tti, target, nextSource(source, matches(getBuildConfig().childIgnorePattern(), childName)));
         if (target != null && targetNode != null) {
           DumpNormalChildNode normalChild = new DumpNormalChildNode();
-          normalChild.setName(car.names.get(method));
+          normalChild.setName(childName);
           normalChild.setDumpNode(targetNode);
           node.addDumpChildNode(normalChild);
         }
@@ -255,9 +288,11 @@ aspect GenerationBackend {
       for (java.lang.reflect.Method method : car.listChildMethods) {
         Iterable<?> targetList = (Iterable<?>) method.invoke(obj);
         DumpListChildNode listChild = new DumpListChildNode();
-        listChild.setName(car.names.get(method));
+        String childName = car.names.get(method);
+        boolean shouldBeInvisisble = matches(getBuildConfig().childIgnorePattern(), childName);
+        listChild.setName(childName);
         for (Object target : targetList) {
-          DumpNode targetNode = transform(tti, target);
+          DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble));
           if (target != null && targetNode != null) {
             listChild.addInnerDumpNode(new InnerDumpNode(targetNode));
           }
@@ -269,7 +304,7 @@ aspect GenerationBackend {
       // -- singleRelation --
       for (java.lang.reflect.Method method : car.singleRelationMethods) {
         Object target = method.invoke(obj);
-        DumpNode targetNode = transform(tti, target);
+        DumpNode targetNode = transform(tti, target, Source.RELATION);
         if (target != null && targetNode != null) {
           DumpNormalRelation normalRelation = new DumpNormalRelation();
           normalRelation.setName(car.names.get(method));
@@ -283,7 +318,7 @@ aspect GenerationBackend {
         DumpListRelation listRelation = new DumpListRelation();
         listRelation.setName(car.names.get(method));
         for (Object target : targetList) {
-          DumpNode targetNode = transform(tti, target);
+          DumpNode targetNode = transform(tti, target, Source.RELATION);
           if (target != null && targetNode != null) {
             listRelation.addInnerDumpNode(new InnerDumpNode(targetNode));
           }
@@ -296,8 +331,10 @@ aspect GenerationBackend {
       for (java.lang.reflect.Method method : car.tokenMethods) {
         Object target = method.invoke(obj);
         if (target != null) {
-          DumpNode targetNode = transform(tti, target);
+          DumpNode targetNode = transform(tti, target, Source.RELATION);
           DumpToken token = null;
+          // TODO check, if Iterable.isAssignableFrom(target.getClass()).
+          //      if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's
           if (targetNode != null && targetNode.isAstNode()) {
             token = new DumpReferenceToken().setValue(targetNode);
           } else {
@@ -317,6 +354,11 @@ aspect GenerationBackend {
     return node;
   }
 
+  private Source DumpAst.nextSource(Source currentSource, boolean shouldBeInvisible) {
+    return currentSource == Source.INVISIBLE_PARENT ? Source.INVISIBLE_PARENT :
+        (shouldBeInvisible ? Source.INVISIBLE_PARENT : Source.PARENT);
+  }
+
   ClassAnalysisResult DumpNode.analyzeClass()
       throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException {
     ClassAnalysisResult result = new ClassAnalysisResult();
@@ -329,31 +371,25 @@ aspect GenerationBackend {
           switch (simpleName) {
             case "Child":
               String singleChildName = invokeName(annotation);
-              if (!matches(buildConfig().childIgnorePattern(), singleChildName)) {
-                result.singleChildMethods.add(method);
-                result.names.put(method, singleChildName);
-              }
+              result.singleChildMethods.add(method);
+              result.names.put(method, singleChildName);
               break;
             case "OptChild":
               String optChildName = invokeName(annotation);
-              if (!matches(buildConfig().childIgnorePattern(), optChildName)) {
-                try {
-                  // the annotated method is "get???Opt", but we want "get???"
-                  java.lang.reflect.Method realGetter = clazz.getMethod("get" + optChildName);
-                  result.singleChildMethods.add(realGetter);
-                  result.names.put(realGetter, optChildName);
-                } catch (NoSuchMethodException e) {
-                  System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazz.getName());
-                  throw new RuntimeException(e);
-                }
+              try {
+                // the annotated method is "get???Opt", but we want "get???"
+                java.lang.reflect.Method realGetter = clazz.getMethod("get" + optChildName);
+                result.singleChildMethods.add(realGetter);
+                result.names.put(realGetter, optChildName);
+              } catch (NoSuchMethodException e) {
+                System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazz.getName());
+                throw new RuntimeException(e);
               }
               break;
             case "ListChild":
               String listChildName = invokeName(annotation);
-              if (!matches(buildConfig().childIgnorePattern(), listChildName)) {
-                result.listChildMethods.add(method);
-                result.names.put(method, listChildName);
-              }
+              result.listChildMethods.add(method);
+              result.names.put(method, listChildName);
               break;
             case "Token":
               // heuristic for relations
@@ -390,8 +426,23 @@ aspect GenerationBackend {
               }
               break;
             case "Attribute":
-              // TODO. check for isNTA=true. then check for whether target is instance of iterable. if so, add to listChildren, otherwise to singelChild
-              // TODO. if isNTA=false, then handle attribute
+              String attributeName = method.getName();
+              boolean isNTA = (boolean) annotation.annotationType().getMethod("isNTA").invoke(annotation);
+              if (isNTA) {
+                if (matches(buildConfig().ntaIncludePattern(), attributeName)) {
+                  if (Iterable.class.isAssignableFrom(method.getReturnType())) {
+                    result.listChildMethods.add(method);
+                    result.names.put(method, attributeName + "()");
+                  } else {
+                    result.singleChildMethods.add(method);
+                    result.names.put(method, attributeName + "()");
+                  }
+                }
+              } else if (matches(buildConfig().attributeIncludePattern(), attributeName)) {
+                // normal attribute
+                result.tokenMethods.add(method);
+                result.names.put(method, attributeName + "()");
+              }
               break;
           }
         }
@@ -410,7 +461,8 @@ aspect GenerationBackend {
   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.attributeIgnorePattern() = java.util.regex.Pattern.compile(getAttributeIgnore());
+  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());
   static boolean ASTNode.matches(java.util.regex.Pattern p, String input) {
     return p.matcher(input).matches();
@@ -468,6 +520,7 @@ aspect GenerationBackend {
 
   class TransformationTransferInformation {
     java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>();
+    java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>();
     java.util.Map<Class<?>, ClassAnalysisResult> classAnalysisResults = new java.util.HashMap<>();
   }
 
diff --git a/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java b/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java
index 454a6ae77f3bd5594b979ef250ab2c1148d3d085..2ff16f10f735c1903c36d8d89b05eeb710a8b732 100644
--- a/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java
+++ b/dumpAst/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/SimpleMain.java
@@ -2,6 +2,8 @@ package de.tudresden.inf.st.jastadd.dumpAst;
 
 import beaver.Parser;
 import de.tudresden.inf.st.jastadd.dumpAst.ast.*;
+import de.tudresden.inf.st.jastadd.dumpAst.ast.ASTNode;
+import de.tudresden.inf.st.jastadd.dumpAst.ast.JastAddList;
 import de.tudresden.inf.st.jastadd.grammar2uml.ast.*;
 import de.tudresden.inf.st.jastadd.grammar2uml.parser.Grammar2UmlParser;
 import de.tudresden.inf.st.jastadd.grammar2uml.scanner.Grammar2UmlScanner;
@@ -16,6 +18,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import static de.tudresden.inf.st.jastadd.dumpAst.SimpleMain.Kind.*;
@@ -119,6 +122,7 @@ public class SimpleMain {
         .disableTypes(".*Comment")
         .dumpAsSource(Paths.get("temp.plantuml"))
         .dumpAsSVG(Paths.get("temp.svg"));
+    System.out.println(Iterable.class.getMethods()[0].getReturnType());
   }
 
   private static void small() throws IOException {
diff --git a/dumpAst/src/main/resources/dumpAst.mustache b/dumpAst/src/main/resources/dumpAst.mustache
index b8105eef93ba3054c4ff207abf38c233af8e0cb7..b0c05305e6ff1c6431d593d7628101c90b3230bc 100644
--- a/dumpAst/src/main/resources/dumpAst.mustache
+++ b/dumpAst/src/main/resources/dumpAst.mustache
@@ -1,76 +1,76 @@
 @startuml
 {{#PrintConfig}}
 scale {{Scale}}
-{{#Headers}}
+  {{#Headers}}
 {{Value}}
-{{/Headers}}
+  {{/Headers}}
 {{/PrintConfig}}
 
 {{#DumpNodes}}
-{{#isAstNode}}
-{{^Invisible}}
+  {{#isAstNode}}
+    {{^Invisible}}
 object "{{label}}" as {{name}} {
-{{#DumpTokens}}
-{{#isDumpValueToken}}
+      {{#DumpTokens}}
+        {{#isDumpValueToken}}
   {{label}} = {{{Value}}}
-{{/isDumpValueToken}}
-{{/DumpTokens}}
+        {{/isDumpValueToken}}
+      {{/DumpTokens}}
 }
-{{/Invisible}}
-{{/isAstNode}}
+    {{/Invisible}}
+  {{/isAstNode}}
 {{/DumpNodes}}
 
 {{#DumpNodes}}
-{{#DumpTokens}}
-{{^Invisible}}
-{{^isDumpValueToken}}
+  {{#DumpTokens}}
+    {{^Invisible}}
+      {{^isDumpValueToken}}
 {{outerNodeName}} ..> {{innerNodeName}} : {{label}}
-{{/isDumpValueToken}}
-{{/Invisible}}
-{{/DumpTokens}}
-{{#DumpChildNodes}}
-{{#isList}}
-{{#InnerDumpNodes}}
-{{#bothVisible}}
+      {{/isDumpValueToken}}
+    {{/Invisible}}
+  {{/DumpTokens}}
+  {{#DumpChildNodes}}
+    {{#isList}}
+      {{#InnerDumpNodes}}
+        {{#bothVisible}}
 {{outerNodeName}} *-- {{innerNodeName}} : {{label}}
-{{/bothVisible}}
-{{/InnerDumpNodes}}
-{{/isList}}
-{{^isList}}
-{{#bothVisible}}
+        {{/bothVisible}}
+      {{/InnerDumpNodes}}
+    {{/isList}}
+    {{^isList}}
+      {{#bothVisible}}
 {{outerNodeName}} *-- {{innerNodeName}} : {{label}}
-{{/bothVisible}}
-{{/isList}}
-{{/DumpChildNodes}}
-{{#DumpRelations}}
-{{#isList}}
-{{#InnerDumpNodes}}
-{{#bothVisible}}
+      {{/bothVisible}}
+    {{/isList}}
+  {{/DumpChildNodes}}
+  {{#DumpRelations}}
+    {{#isList}}
+      {{#InnerDumpNodes}}
+        {{#bothVisible}}
 {{outerNodeName}} {{#Bidirectional}}<{{/Bidirectional}}--> {{innerNodeName}} : {{label}}
-{{/bothVisible}}
-{{/InnerDumpNodes}}
-{{/isList}}
-{{^isList}}
-{{#bothVisible}}
+        {{/bothVisible}}
+      {{/InnerDumpNodes}}
+    {{/isList}}
+    {{^isList}}
+      {{#bothVisible}}
 {{outerNodeName}} {{#Bidirectional}}<{{/Bidirectional}}--> {{innerNodeName}} : {{label}}
-{{/bothVisible}}
-{{/isList}}
-{{/DumpRelations}}
-{{^Invisible}}
-{{#InvisiblePath}}
-{{#InnerDumpNodes}}
+      {{/bothVisible}}
+    {{/isList}}
+  {{/DumpRelations}}
+  {{^Invisible}}
+    {{#InvisiblePath}}
+      {{#InnerDumpNodes}}
 {{outerNodeName}} o.. {{innerNodeName}}
-{{/InnerDumpNodes}}
-{{/InvisiblePath}}
-{{/Invisible}}
+      {{/InnerDumpNodes}}
+    {{/InvisiblePath}}
+  {{/Invisible}}
 {{/DumpNodes}}
 {{#BuildConfig}}
-{{#Debug}}
+  {{#Debug}}
 legend right
   %date()
   dumpAst: {{version}}
   plantuml: %version()
 endlegend
-{{/Debug}}
+  {{/Debug}}
 {{/BuildConfig}}
 @enduml
diff --git a/testDumper/src/main/jastadd/testDumper.jrag b/testDumper/src/main/jastadd/testDumper.jrag
index c27464bea4ff4586b04c35efdb77a20412b3e36e..7c98b5787378aecfed4eae0e08664f704cb68c58 100644
--- a/testDumper/src/main/jastadd/testDumper.jrag
+++ b/testDumper/src/main/jastadd/testDumper.jrag
@@ -26,4 +26,7 @@ aspect Grammar {
     result.add(inner);
     return result;
   }
+
+  syn int Root.simpleAttr() = 42;
+  syn A Root.referenceAttr() = getA();
 }
diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestExcluded.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestExcluded.java
index 4faf6639b16f68cd1fae55527a9a4a97425cec5f..87588648dad540b88ba856b349c57c4a95d84cd3 100644
--- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestExcluded.java
+++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestExcluded.java
@@ -270,7 +270,7 @@ public class TestExcluded {
   }
 
   @Test
-  public void testChildrenDefault() throws IOException {
+  public void testChildrenDefault() {
     /*  Root
         |- a
            |- b  - - -.
@@ -286,7 +286,6 @@ public class TestExcluded {
     }), null);
     root.getA().getB().setOneA(root.getA().getMyC().getA());
 
-    Dumper.read(root).disableTypes("C").dumpAsPNG(Paths.get("test.png"));
     List<DumpNode> nodes = TestUtils.dumpModel(root);
     assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(
         ROOT_NAME, A_NAME, A2_Name, B_NAME, B2_NAME, C_NAME);
@@ -295,7 +294,6 @@ public class TestExcluded {
         tuple("MyC", C_NAME), tuple("B", B_NAME));
   }
 
-  @Disabled("a2 and b2 are included in output, so currently not working as intended")
   @Test
   public void testChildrenExclude() {
     /*  Root
diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java
new file mode 100644
index 0000000000000000000000000000000000000000..7973addd20f1ba2afbd78626af9e2927b4c26546
--- /dev/null
+++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestIncluded.java
@@ -0,0 +1,97 @@
+package de.tudresden.inf.st.jastadd.testDumper;
+
+import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode;
+import org.jastadd.testDumper.ast.Root;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static de.tudresden.inf.st.jastadd.testDumper.TestUtils.*;
+import static org.assertj.core.api.Assertions.*;
+
+public class TestIncluded {
+
+  @Test
+  public void testValueAttributeDefault() {
+    Root root = createRoot(null, null);
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root);
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME);
+    DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
+    assertThat(valueTokens(actualRoot)).containsOnly(entry("Name", ROOT_NAME));
+  }
+
+  @Test
+  public void testValueAttributeIncluded() {
+    Root root = createRoot(null, null);
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.includeAttributes("simpleAttr"));
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME);
+    DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
+    assertThat(valueTokens(actualRoot)).containsOnly(entry("Name", ROOT_NAME), entry("simpleAttr()", 42));
+  }
+
+  @Test
+  public void testReferenceAttributeDefault() {
+    Root root = createRoot(createA(A_NAME), null);
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root);
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, A_NAME);
+    DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
+    assertThat(referenceTokens(actualRoot)).isEmpty();
+  }
+
+    @Test
+  public void testReferenceAttributeIncluded() {
+    Root root = createRoot(createA(A_NAME), null);
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.includeAttributes("referenceAttr"));
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, A_NAME);
+    DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
+    assertThatMapOf(referenceTokens(actualRoot)).containsOnly(tuple("referenceAttr()", A_NAME));
+  }
+
+  @Test
+  public void testNormalNTADefault() {
+    Root root = createRoot(null, createC(C_NAME));
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root);
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, C_NAME);
+    DumpNode actualC = TestUtils.findByName(nodes, C_NAME);
+    assertThatMapOf(normalChildren(actualC)).isEmpty();
+  }
+
+    @Test
+  public void testNormalNTAIncluded() {
+    Root root = createRoot(null, createC(C_NAME));
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.includeNonterminalAttributes("getCalculated"));
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, C_NAME, "Calculated-" + C_NAME);
+    DumpNode actualC = TestUtils.findByName(nodes, C_NAME);
+    assertThatMapOf(normalChildren(actualC)).containsOnly(tuple("getCalculated()", "Calculated-" + C_NAME));
+  }
+
+  @Test
+  public void testListNTADefault() {
+    Root root = createRoot(null, createC(C_NAME));
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root);
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, C_NAME);
+    DumpNode actualC = TestUtils.findByName(nodes, C_NAME);
+    assertThat(listChildren(actualC)).isEmpty();
+
+  }
+
+  @Disabled("NTA lists not working at the moment")
+  @Test
+  public void testListNTAIncluded() {
+    // TODO make the test not failing
+    Root root = createRoot(null, createC(C_NAME));
+
+    List<DumpNode> nodes = TestUtils.dumpModel(root, db -> db.includeNonterminalAttributes("AlsoCalculated"));
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactly(ROOT_NAME, C_NAME, "AlsoCalculated-" + C_NAME);
+    DumpNode actualC = TestUtils.findByName(nodes, C_NAME);
+    assertThatMapOf(listChildren(actualC), "getAlsoCalculated()").containsExactly("AlsoCalculated-" + C_NAME);
+  }
+}
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 d40a297d95223a7e989ccdbcdeac08516f53d9a6..9f45108fb7b6eaceb51424605e457d1e3efd052f 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
@@ -30,7 +30,6 @@ public class TestSimple {
     Root root = createRoot(createA(A_NAME), null);
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(2, nodes.size());
     assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME);
     DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
     assertEquals(1, actualRoot.getNumDumpToken());
@@ -57,7 +56,6 @@ public class TestSimple {
     Root root = createRoot(null, createC(C_NAME));
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(2, nodes.size());
     assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, C_NAME);
     DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME);
     assertEquals(1, actualRoot.getNumDumpToken());
@@ -72,7 +70,7 @@ public class TestSimple {
     root.getB(0).setOneA(root.getA());
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(4, nodes.size());
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
     DumpNode actualB = TestUtils.findByName(nodes, B_NAME);
     assertThatMapOf(normalRelationChildren(actualB)).containsExactlyInAnyOrder(tuple("OneA", A_NAME));
   }
@@ -97,7 +95,7 @@ public class TestSimple {
     root.getB(0).setMaybeC(root.getC());
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(4, nodes.size());
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
     DumpNode actualB = TestUtils.findByName(nodes, B_NAME);
     assertThatMapOf(normalRelationChildren(actualB)).containsExactlyInAnyOrder(tuple("MaybeC", C_NAME));
   }
@@ -108,7 +106,7 @@ public class TestSimple {
     root.getC().setBiA1(root.getA());
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(4, nodes.size());
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
     // bidirectional relations are currently not found, instead there will be two unidirectional ones
     DumpNode actualA = TestUtils.findByName(nodes, A_NAME);
     assertThatMapOf(normalRelationChildren(actualA)).containsExactlyInAnyOrder(tuple("BiC1", C_NAME));
@@ -122,7 +120,7 @@ public class TestSimple {
     root.getC().addBiA2(root.getA());
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(4, nodes.size());
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
     // bidirectional relations are currently not found, instead there will be two unidirectional ones
     DumpNode actualA = TestUtils.findByName(nodes, A_NAME);
     assertThatMapOf(normalRelationChildren(actualA)).containsExactlyInAnyOrder(tuple("BiC2", C_NAME));
@@ -136,7 +134,7 @@ public class TestSimple {
     root.getC().setBiA3(root.getA());
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(4, nodes.size());
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
     // bidirectional relations are currently not found, instead there will be two unidirectional ones
     DumpNode actualA = TestUtils.findByName(nodes, A_NAME);
     assertThatMapOf(normalRelationChildren(actualA)).containsExactlyInAnyOrder(tuple("BiC3", C_NAME));
@@ -150,7 +148,7 @@ public class TestSimple {
     root.getC().setRawReference(root.getA());
 
     List<DumpNode> nodes = TestUtils.dumpModel(root);
-    assertEquals(4, nodes.size());
+    assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, A_NAME, B_NAME, C_NAME);
     DumpNode actualC = TestUtils.findByName(nodes, C_NAME);
     assertThatMapOf(referenceTokens(actualC)).containsExactlyInAnyOrder(tuple(TOKEN_LABEL_RAW_REFERENCE, A_NAME));
   }