diff --git a/grammar2uml/build.gradle b/grammar2uml/build.gradle
index 5f4002d3e054c8a15eca2e1b4b73d4db96fd9c9e..01b27961201fb746a8fcde822e16b3338770e4c1 100644
--- a/grammar2uml/build.gradle
+++ b/grammar2uml/build.gradle
@@ -225,13 +225,18 @@ task printVersion() {
 task setDevVersionForCI() {
     doFirst {
         def props = new Properties()
-        props['version'] = version + "-$System.env.CI_PIPELINE_IID"
+        props['version'] = version + "-dev-$System.env.CI_PIPELINE_IID"
         props.store(file(versionFile).newWriter(), null)
     }
 }
 
 group = 'de.tudresden.inf.st'
 
+java {
+    withJavadocJar()
+    withSourcesJar()
+}
+
 publishing {
     publications {
         maven(MavenPublication) {
diff --git a/grammar2uml/src/main/jastadd/Grammar2Uml.relast b/grammar2uml/src/main/jastadd/Grammar2Uml.relast
index 36a4456c05a799312fd24be8f49e89af15d4b457..d3897c8833e7c552ae863d95d74867fd1e5e5095 100644
--- a/grammar2uml/src/main/jastadd/Grammar2Uml.relast
+++ b/grammar2uml/src/main/jastadd/Grammar2Uml.relast
@@ -1,6 +1,8 @@
-Grammar2Uml ::= Program <FileName> Folder* <StyleDefinition:StyleDefinition> ;
+Grammar2Uml ::= Program <FileName> Folder* StyleInformation <StyleDefinition:StyleDefinition> ;
 
 Folder ::= <Name:String> <Active:boolean> ;
 rel Folder.Type* <-> TypeDecl.SourceFolder?;
 
 Style ::= <BackgroundColor> <InlineAsSuperType:boolean> ;
+
+StyleInformation ::= <ComputedColor> ;
diff --git a/grammar2uml/src/main/jastadd/MustacheNodes.relast b/grammar2uml/src/main/jastadd/MustacheNodes.relast
index 1b65fc8bc8fb452013f63dbf1e7e46edb5f62ae7..eb94ce4223bf23163f2e5028e71725d0e353e73b 100644
--- a/grammar2uml/src/main/jastadd/MustacheNodes.relast
+++ b/grammar2uml/src/main/jastadd/MustacheNodes.relast
@@ -2,11 +2,11 @@ MGrammar2Uml ::= Folder:MFolder* OtherType:MTypeDecl* Containment:MContainment*
 MFolder ::= InnerTypeDecl:MTypeDecl* <Active:boolean> ;
 MTypeDecl ::= InnerTokenComponent:MTokenComponent* <Name> Style;
 MTokenComponent;
-abstract MContainment ::= <Label:String> ;
+abstract MContainment ::= <Label:String> <Computed:boolean> ;
 MSingleContainment : MContainment;
 MOptContainment : MContainment;
 MListContainment : MContainment;
-MRelation ::= <Label> <LeftModifier> <RightModifier> <Bidirectional:boolean>;
+MRelation ::= <Label> <LeftLabel> <RightLabel> <Bidirectional:boolean>;
 MInheritance;
 
 rel MGrammar2Uml.Grammar2Uml -> Grammar2Uml;
@@ -17,6 +17,5 @@ rel MContainment.Type -> MTypeDecl;
 rel MContainment.Component -> MTypeDecl;
 rel MRelation.Left -> MTypeDecl;
 rel MRelation.Right -> MTypeDecl;
-//rel MTypeDecl.SuperClass? -> MTypeDecl;
 rel MInheritance.SuperClass -> MTypeDecl;
 rel MInheritance.SubClass -> MTypeDecl;
diff --git a/grammar2uml/src/main/jastadd/backend/Configuration.jadd b/grammar2uml/src/main/jastadd/backend/Configuration.jadd
index 8dc259407fd5fff7e314af0875e318b0aaa288e2..bbd40c01c1497f08fa50f2059b7ebaf87af2d4f6 100644
--- a/grammar2uml/src/main/jastadd/backend/Configuration.jadd
+++ b/grammar2uml/src/main/jastadd/backend/Configuration.jadd
@@ -1,2 +1,5 @@
 aspect Configuration {
+  public static StyleInformation StyleInformation.createDefault() {
+    return new StyleInformation().setComputedColor("blue");
+  }
 }
diff --git a/grammar2uml/src/main/jastadd/backend/Generation.jadd b/grammar2uml/src/main/jastadd/backend/Generation.jadd
index 39fe55dfac89034894c6821fae6e050efff69630..ffce7921ab1b335c7c7878e0dc79e7707d691273 100644
--- a/grammar2uml/src/main/jastadd/backend/Generation.jadd
+++ b/grammar2uml/src/main/jastadd/backend/Generation.jadd
@@ -47,6 +47,7 @@ aspect AttributesForMustache {
   syn String MContainment.typeName() = "\"" + getType().getName() + "\"";
   syn String MContainment.componentName() = "\"" + getComponent().getName() + "\"";
   syn String MContainment.modifier();
+  syn String MContainment.computedColor() = grammar2uml().getStyleInformation().getComputedColor();
   eq MSingleContainment.modifier() = "\"1\"";
   eq MOptContainment.modifier() = "\"0 .. 1\"";
   eq MListContainment.modifier() = "\"*\"";
@@ -82,27 +83,32 @@ aspect AttributesForMustache {
   syn MRelation Relation.toMRelation();
   eq DirectedRelation.toMRelation() {
     MRelation result = new MRelation();
-    result.setRightModifier(getSource().toMRelationModifier());
+    result.setRightLabel("\"" + getSource().toMRelationModifier() + getSource().maybeName() + "\"");
     result.setBidirectional(false);
     return result;
   }
   eq BidirectionalRelation.toMRelation() {
     MRelation result = new MRelation();
-    result.setLeftModifier(getRight().toMRelationModifier());
-    result.setRightModifier(getLeft().toMRelationModifier());
+    result.setLeftLabel("\"" + getRight().toMRelationModifier() + getRight().maybeName() + "\"");
+    result.setRightLabel("\"" + getLeft().toMRelationModifier() + getLeft().maybeName() + "\"");
     result.setBidirectional(true);
     return result;
   }
 
   // --- toMRelationModifier ---
   syn String Role.toMRelationModifier();
-  eq NormalRole.toMRelationModifier() = "\"1\"";
-  eq ListRole.toMRelationModifier() = "\"*\"";
-  eq OptRole.toMRelationModifier() = "\"0 .. 1\"";
+  eq NormalRole.toMRelationModifier() = "1";
+  eq ListRole.toMRelationModifier() = "*";
+  eq OptRole.toMRelationModifier() = "0 .. 1";
   eq UnnamedRole.toMRelationModifier() {
     throw new RuntimeException("UnnamedRole cannot be converted to MRelation");
   }
 
+  // --- maybeName ---
+  syn String Role.maybeName() = "";
+  eq NavigableRole.maybeName() = " " + getName();
+
+  // --- createDefaultStyle ---
   private Style TypeDecl.createDefaultStyle() {
     return new Style().setBackgroundColor("white");
   }
@@ -136,6 +142,9 @@ aspect AttributesForMustache {
           if (!component.getName().isEmpty() && !component.getName().equals(component.asTypeComponent().getTypeDecl().getName())) {
             containment.setLabel(component.getName());
           }
+          if (component.getNTA()) {
+            containment.setComputed(true);
+          }
           result.addContainment(containment);
         }
       }
diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlProcessor.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlProcessor.java
index 22d6d5211cafb09bb800d53a0d44fd09136bd438..d20d5b4bf8bdc7f650eb05e50e10d00cae80d5bb 100644
--- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlProcessor.java
+++ b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlProcessor.java
@@ -26,11 +26,16 @@ public class Grammar2UmlProcessor {
   private final List<String> inputGrammarFiles = new ArrayList<>();
   private boolean verbose;
   private boolean useDefaultFolders;
-  private final List<Folder> folders = new ArrayList<>();
-  private Grammar2Uml grammar2uml = null;
+  private final Grammar2Uml grammar2uml;
+
   private final List<Consumer<Grammar2Uml>> callbacks = new ArrayList<>();
   private StyleDefinition styleDefinition = (typeDecl, style) -> {};
 
+  public Grammar2UmlProcessor() {
+    grammar2uml = new Grammar2Uml();
+    grammar2uml.setStyleInformation(StyleInformation.createDefault());
+  }
+
   public Grammar2UmlProcessor addGrammar(String... inputGrammarFiles) {
     Collections.addAll(this.inputGrammarFiles, inputGrammarFiles);
     return this;
@@ -52,7 +57,7 @@ public class Grammar2UmlProcessor {
    * @return this
    */
   public Grammar2UmlProcessor addFolder(Folder... folders) {
-    Collections.addAll(this.folders, folders);
+    Arrays.stream(folders).forEach(this.grammar2uml::addFolder);
     return this;
   }
 
@@ -88,6 +93,11 @@ public class Grammar2UmlProcessor {
     return this;
   }
 
+  public Grammar2UmlProcessor setComputedColor(String color) {
+    this.grammar2uml.getStyleInformation().setComputedColor(color);
+    return this;
+  }
+
   /**
    * Writes the representation to the given destination file.
    *
@@ -189,24 +199,8 @@ public class Grammar2UmlProcessor {
     }
   }
 
-//  private void debugAttributes() {
-//    for (Folder folder : grammar2uml.getFolderList()) {
-//      System.out.println(folder.getName() + ": active=" + folder.getActive() + ", mFolder.active=" + folder.toMustache().getActive());
-//    }
-//    for (TypeDecl typeDecl : grammar2uml.getProgram().typeDecls().stream()
-//        .sorted(Comparator.comparing(TypeDecl::getName))
-//        .collect(Collectors.toList())) {
-//      MTypeDecl mTypeDecl = typeDecl.toMustache();
-//      System.out.println(typeDecl.getName() + ": " + String.join(", ",
-//          "relates=" + typeDecl.relatesToActiveTypeDecl(),
-//          "folderInactive+Unrelated=" + mTypeDecl.folderInactiveAndUnrelated(),
-//          "folderInactive+Related=" + mTypeDecl.folderInactiveAndRelated(),
-//          "folderActive=" + mTypeDecl.containingFolderActive()));
-//    }
-//  }
-
   private void build() throws CompilerException {
-    if (grammar2uml != null) {
+    if (grammar2uml.getProgram() != null) {
       return;  // already built
     }
 
@@ -215,7 +209,6 @@ public class Grammar2UmlProcessor {
     }
 
     Program program = new Program();
-    grammar2uml = new Grammar2Uml();
     for (String inputGrammarFileName : inputGrammarFiles) {
       printMessage("Parsing " + inputGrammarFileName);
       GrammarFile inputGrammar;
@@ -239,10 +232,6 @@ public class Grammar2UmlProcessor {
       }
     }
 
-    for (Folder folder : folders) {
-      grammar2uml.addFolder(folder);
-    }
-
     grammar2uml.setStyleDefinition(styleDefinition);
     grammar2uml.setProgram(program);
     grammar2uml.treeResolveAll();
diff --git a/grammar2uml/src/main/resources/Containment.mustache b/grammar2uml/src/main/resources/Containment.mustache
index 82b635107aacd91ac77d226a8865fdc0dc8dc7f2..bbd15dd9617905f2abb49340e3e21a096f82ceb5 100644
--- a/grammar2uml/src/main/resources/Containment.mustache
+++ b/grammar2uml/src/main/resources/Containment.mustache
@@ -1,3 +1,3 @@
 {{#atLeastOneInActiveFolder}}
-{{{typeName}}} *-- {{{modifier}}} {{{componentName}}} {{#Label}}: {{Label}}{{/Label}}
+{{{typeName}}} *-[#black{{#Computed}},#{{{computedColor}}}{{/Computed}}]- {{{modifier}}} {{{componentName}}} {{#Label}}: {{Label}}{{/Label}}
 {{/atLeastOneInActiveFolder}}
diff --git a/grammar2uml/src/main/resources/Relation.mustache b/grammar2uml/src/main/resources/Relation.mustache
index 14c6c9725f156732973702b52ef9996927fc2230..78f16e3990a91c3b3ebd49f0cd67c65de20554ff 100644
--- a/grammar2uml/src/main/resources/Relation.mustache
+++ b/grammar2uml/src/main/resources/Relation.mustache
@@ -1,3 +1,3 @@
 {{#atLeastOneInActiveFolder}}
-{{{leftName}}} {{{leftModifier}}} {{#isBidirectional}}<{{/isBidirectional}}-[norank]-> {{{rightModifier}}} {{{rightName}}} {{#Label}}: {{Label}}{{/Label}}
+{{{leftName}}} {{{LeftLabel}}} {{#isBidirectional}}<{{/isBidirectional}}-[norank]-> {{{RightLabel}}} {{{rightName}}} {{#Label}}: {{Label}}{{/Label}}
 {{/atLeastOneInActiveFolder}}
diff --git a/grammar2uml/src/main/resources/grammar2umlVersion.properties b/grammar2uml/src/main/resources/grammar2umlVersion.properties
index 1b6f9fba77a949f4802f567423cdaff207d59ee7..2848c21be747cb0f19e9dfcaa68862b07b42d9b5 100644
--- a/grammar2uml/src/main/resources/grammar2umlVersion.properties
+++ b/grammar2uml/src/main/resources/grammar2umlVersion.properties
@@ -1,2 +1,2 @@
-#Fri Sep 30 14:31:26 CEST 2022
-version=0.2.6
+#Tue Oct 04 16:43:05 CEST 2022
+version=0.2.7