diff --git a/dumpAst.base/build.gradle b/dumpAst.base/build.gradle
index c813e63f6966f638e106498364ffb4498ff60f4f..88ccfde78f90ad7ccb280fab03e417a534ccced3 100644
--- a/dumpAst.base/build.gradle
+++ b/dumpAst.base/build.gradle
@@ -179,6 +179,15 @@ publishing {
     }
 }
 
+// --- Misc ---
+task ensureNoTrainlingNewlineForRelationStyleMustache() {
+    doFirst {
+        def text = project.file("src/main/resources/RelationStyle.mustache").text
+        project.file("src/main/resources/RelationStyle.mustache").write(text.strip())
+    }
+}
+
 // --- Task order ---
+compileJava.dependsOn ensureNoTrainlingNewlineForRelationStyleMustache
 generateAst.dependsOn relast
 publish.dependsOn jar
diff --git a/dumpAst.base/src/main/jastadd/DumpAst.relast b/dumpAst.base/src/main/jastadd/DumpAst.relast
index f66e04b7aca3b740004a7fc24dea2584a19945f9..5abf5872ff94270d670b9d1acd747019560d025f 100644
--- a/dumpAst.base/src/main/jastadd/DumpAst.relast
+++ b/dumpAst.base/src/main/jastadd/DumpAst.relast
@@ -5,24 +5,24 @@ DumpNode ::=  DumpChildNode* DumpToken* DumpRelation*
  <Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> <Computed:boolean> <ManualStereotypes>
  /InvisiblePath/ ;
 
-InnerDumpNode ::= <OriginalIndex:int> <Label> <TextColor> ;
+InnerDumpNode ::= <OriginalIndex:int> <Label> <LineColor> <TextColor> ;
 rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner? ;
-InnerRelationDumpNode ::= <OriginalIndex:int> <Label> <TextColor> ;
+InnerRelationDumpNode ::= <OriginalIndex:int> <Label> <LineColor> <TextColor> ;
 rel InnerRelationDumpNode.DumpNode <-> DumpNode.ContainerOfRelationInner* ;
 
-abstract DumpChildNode ::= <Name> <Computed:boolean> ;
-DumpNormalChildNode : DumpChildNode ::= <TextColor> ;
+abstract DumpChildNode ::= <Label> <Computed:boolean> ;
+DumpNormalChildNode : DumpChildNode ::= <LineColor> <TextColor> ;
 rel DumpNormalChildNode.DumpNode <-> DumpNode.ContainerOfNormalChild? ;
 DumpListChildNode : DumpChildNode ::= InnerDumpNode* ;
 
-abstract DumpToken ::= <Name> <Computed:boolean> ;
+abstract DumpToken ::= <Label> <Computed:boolean> ;
 DumpReferenceToken : DumpToken ;
 rel DumpReferenceToken.Value -> DumpNode ;
 DumpReferenceListToken : DumpToken ::= InnerRelationDumpNode* ;
 DumpValueToken : DumpToken ::= <Value:Object> ;
 
-abstract DumpRelation ::= <Name> <Bidirectional:boolean> ;
-DumpNormalRelation : DumpRelation ::= <TextColor> ;
+abstract DumpRelation ::= <Label> <Bidirectional:boolean> ;
+DumpNormalRelation : DumpRelation ::= <LineColor> <TextColor> ;
 rel DumpNormalRelation.DumpNode -> DumpNode ;
 DumpListRelation : DumpRelation ::= InnerRelationDumpNode* ;
 
@@ -74,4 +74,4 @@ PrintConfig ::= Header*
 Header ::= <Value> ;
 
 NodeStyle ::= <Label> <BackgroundColor> <TextColor> <StereoTypes> ;
-RelationStyle ::= <Label> <TextColor> ;
+RelationStyle ::= <Label> <LineColor> <TextColor> ;
diff --git a/dumpAst.base/src/main/jastadd/Frontend.jrag b/dumpAst.base/src/main/jastadd/Frontend.jrag
index 86f36a3f6e537553bb68ea6ccce519ff38992897..41319aa812239c1a3e8b273e7aaf6740065912ec 100644
--- a/dumpAst.base/src/main/jastadd/Frontend.jrag
+++ b/dumpAst.base/src/main/jastadd/Frontend.jrag
@@ -12,7 +12,7 @@ aspect Frontend {
 
   @FunctionalInterface
   public interface RelationStyleDefinition<ASTNODE> {
-    void style(ASTNODE source, ASTNODE target, String context, RelationStyle style);
+    void style(ASTNODE source, ASTNODE target, RelationStyle style);
   }
 
   public void NodeStyle.useSimpleLabel() {
diff --git a/dumpAst.base/src/main/jastadd/Printing.jrag b/dumpAst.base/src/main/jastadd/Printing.jrag
index eb16c8074de6935e485db0ad0d0d089fd3d97b41..6325c9da6411abefd31a5b8df62631c4d18ff8bd 100644
--- a/dumpAst.base/src/main/jastadd/Printing.jrag
+++ b/dumpAst.base/src/main/jastadd/Printing.jrag
@@ -19,9 +19,9 @@ aspect Printing {
   syn String DumpNode.name() = getName();  // might change in the future
 
   // --- label ---
-  syn String DumpChildNode.label() = getName() + (getComputed() ? "()" : "");
-  syn String DumpRelation.label() = getName();
-  syn String DumpToken.label() = getName() + (getComputed() ? "()" : "");
+  syn String DumpChildNode.label() = getLabel() + (getComputed() ? "()" : "");
+  syn String DumpRelation.label() = getLabel();
+  syn String DumpToken.label() = getLabel() + (getComputed() ? "()" : "");
   syn String DumpNode.label() = getLabel();
   inh String InnerDumpNode.label();
   inh String InnerRelationDumpNode.label();
diff --git a/dumpAst.base/src/main/jastadd/TemplateContext.jrag b/dumpAst.base/src/main/jastadd/TemplateContext.jrag
index a559311c3c6fb8ae58a93cf19ea72a1b81ba5936..0f313732f5d521d08a2b8b29d1f5331137638bb3 100644
--- a/dumpAst.base/src/main/jastadd/TemplateContext.jrag
+++ b/dumpAst.base/src/main/jastadd/TemplateContext.jrag
@@ -60,6 +60,12 @@ aspect TemplateContext {
     }
   }
 
+  // --- hasLineColor ---
+  syn boolean InnerDumpNode.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty();
+  syn boolean InnerRelationDumpNode.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty();
+  syn boolean DumpNormalChildNode.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty();
+  syn boolean DumpNormalRelation.needRelationStyling() = !getLineColor().isEmpty() || !getTextColor().isEmpty();
+
   // --- stereotypeList ---
   syn String DumpNode.stereotypeList() {
     StringBuilder sb = new StringBuilder(getManualStereotypes());
diff --git a/dumpAst.base/src/main/jastadd/ToYaml.jrag b/dumpAst.base/src/main/jastadd/ToYaml.jrag
index ba9c7e8b72bde8a6112ee63a2c374176ef664fa6..51f5eee938fd792a6b1d027b8c4bd307dfe8acc2 100644
--- a/dumpAst.base/src/main/jastadd/ToYaml.jrag
+++ b/dumpAst.base/src/main/jastadd/ToYaml.jrag
@@ -32,9 +32,9 @@ aspect ToYaml {
     addYamledList(result, "Headers", getHeaderList(), fromRelation);
 
     // tokens
-    result.put("scale", getScale());
-    result.put("version", getVersion());
-    result.put("orderChildren", getOrderChildren());
+    result.put("Scale", getScale());
+    result.put("Version", getVersion());
+    result.put("OrderChildren", getOrderChildren());
 
     // attributes
     result.put("debug", debug());
@@ -44,7 +44,7 @@ aspect ToYaml {
   syn MappingElement Header.toYaml(boolean fromRelation) {
     MappingElement result = new MappingElement();
     // tokens
-    result.put("value", getValue());
+    result.put("Value", getValue());
     return result;
   }
 
@@ -59,13 +59,13 @@ aspect ToYaml {
     }
 
     // tokens
-    result.put("name", getName());
+    result.put("Name", getName());
     if (!fromRelation) {
-      result.put("computed", getComputed());
-      result.put("label", getLabel());
-      result.put("backgroundColor", getBackgroundColor());
-      result.put("textColor", getTextColor());
-      result.put("invisible", getInvisible());
+      result.put("Computed", getComputed());
+      result.put("Label", getLabel());
+      result.put("BackgroundColor", getBackgroundColor());
+      result.put("TextColor", getTextColor());
+      result.put("Invisible", getInvisible());
     }
 
     // attributes
@@ -90,8 +90,8 @@ aspect ToYaml {
   syn MappingElement DumpChildNode.toYaml(boolean fromRelation) {
     MappingElement result = new MappingElement();
     // tokens
-    result.put("name", getName());
-    result.put("computed", getComputed());
+    result.put("Label", getLabel());
+    result.put("Computed", getComputed());
     // attributes
     result.put("label", label());
     result.put("isList", isList());
@@ -102,9 +102,13 @@ aspect ToYaml {
 
   syn MappingElement DumpNormalChildNode.toYaml(boolean fromRelation) {
     MappingElement result = super.toYaml(fromRelation);
+    // tokens
+    result.put("LineColor", getLineColor());
+    result.put("TextColor", getTextColor());
     // attributes
     result.put("bothVisible", bothVisible());
     result.put("innerNodeName", innerNodeName());
+    result.put("needRelationStyling", needRelationStyling());
     return result;
   }
 
@@ -118,8 +122,8 @@ aspect ToYaml {
   syn MappingElement DumpToken.toYaml(boolean fromRelation) {
     MappingElement result = new MappingElement();
     // tokens
-    result.put("name", getName());
-    result.put("computed", getComputed());
+    result.put("Label", getLabel());
+    result.put("Computed", getComputed());
     // attributes
     result.put("isList", isList());
     result.put("label", label());
@@ -130,7 +134,7 @@ aspect ToYaml {
   syn MappingElement DumpValueToken.toYaml(boolean fromRelation) {
     MappingElement result = super.toYaml(fromRelation);
     // tokens
-    result.put("value", getValue().toString());
+    result.put("Value", getValue().toString());
     return result;
   }
 
@@ -157,8 +161,8 @@ aspect ToYaml {
   syn MappingElement DumpRelation.toYaml(boolean fromRelation) {
     MappingElement result = new MappingElement();
     // tokens
-    result.put("name", getName());
-    result.put("bidirectional", getBidirectional());
+    result.put("Label", getLabel());
+    result.put("Bidirectional", getBidirectional());
     // attributes
     result.put("isList", isList());
     result.put("label", label());
@@ -168,10 +172,14 @@ aspect ToYaml {
 
   syn MappingElement DumpNormalRelation.toYaml(boolean fromRelation) {
     MappingElement result = super.toYaml(fromRelation);
+    // tokens
+    result.put("LineColor", getLineColor());
+    result.put("TextColor", getTextColor());
     // attributes
     result.put("bothVisible", bothVisible());
     result.put("innerNodeName", innerNodeName());
     result.put("innerNotNullOrEmpty", innerNotNullOrEmpty());
+    result.put("needRelationStyling", needRelationStyling());
     return result;
   }
 
@@ -184,22 +192,30 @@ aspect ToYaml {
 
   syn MappingElement InnerDumpNode.toYaml(boolean fromRelation) {
     MappingElement result = new MappingElement();
+    // tokens
+    result.put("LineColor", getLineColor());
+    result.put("TextColor", getTextColor());
     // attributes
     result.put("bothVisible", bothVisible());
     result.put("innerNodeName", innerNodeName());
     result.put("outerNodeName", outerNodeName());
     result.put("label", label());
+    result.put("needRelationStyling", needRelationStyling());
     return result;
   }
 
   syn MappingElement InnerRelationDumpNode.toYaml(boolean fromRelation) {
     MappingElement result = new MappingElement();
+    // tokens
+    result.put("LineColor", getLineColor());
+    result.put("TextColor", getTextColor());
     // attributes
     result.put("bothVisible", bothVisible());
     result.put("innerNodeName", innerNodeName());
     result.put("innerNotNullOrEmpty", innerNotNullOrEmpty());
     result.put("outerNodeName", outerNodeName());
     result.put("label", label());
+    result.put("needRelationStyling", needRelationStyling());
     return result;
   }
 
diff --git a/dumpAst.base/src/main/jastadd/Transform.jadd b/dumpAst.base/src/main/jastadd/Transform.jadd
index c30ecbc9a4e9eb328f39ad7aa5cb5701eb31bc8f..f0468843188d59aa1c03112690c6e1b31a2c1637 100644
--- a/dumpAst.base/src/main/jastadd/Transform.jadd
+++ b/dumpAst.base/src/main/jastadd/Transform.jadd
@@ -172,7 +172,7 @@ aspect Transform {
     DumpNode targetNode = transform(tti, target, options.asNormal(false).allowNullObjectsOnce());
     if (targetNode != null) {
       DumpNormalChildNode normalChild = new DumpNormalChildNode();
-      normalChild.setName(childName + (containmentMethod.isOptChildMethod() ? "?" : ""));
+      normalChild.setLabel(childName + (containmentMethod.isOptChildMethod() ? "?" : ""));
       normalChild.setDumpNode(targetNode);
       normalChild.setComputed(false);
       node.addDumpChildNode(normalChild);
@@ -189,7 +189,7 @@ aspect Transform {
     DumpListChildNode listChild = new DumpListChildNode();
     listChild.setComputed(false);
     String childName = containmentMethod.getName();
-    listChild.setName(childName);
+    listChild.setLabel(childName);
     node.addDumpChildNode(listChild);
 
     int index = -1;
@@ -229,7 +229,7 @@ aspect Transform {
     DumpNode targetNode = transform(tti, otherMethod.getMethod().invoke(obj), options.asNormal(false).computed(computed).allowNullObjectsOnce());
     if (targetNode != null) {
       DumpNormalChildNode normalChild = new DumpNormalChildNode();
-      normalChild.setName(childName);
+      normalChild.setLabel(childName);
       normalChild.setDumpNode(targetNode);
       normalChild.setComputed(computed);
       node.addDumpChildNode(normalChild);
@@ -251,7 +251,7 @@ aspect Transform {
     DumpListChildNode listChild = new DumpListChildNode();
     boolean computed = otherMethod.asListChildMethod().isNTAListChildMethod();
     listChild.setComputed(computed);
-    listChild.setName(childName);
+    listChild.setLabel(childName);
     boolean notAddedYet = true;
     for (Object target : targetList) {
       DumpNode targetNode = transform(tti, target, options.asNormal(false).computed(computed));
@@ -280,7 +280,7 @@ aspect Transform {
     DumpNode targetNode = transform(tti, target, options.asRelation());
     if (targetNode != null) {
       DumpNormalRelation normalRelation = new DumpNormalRelation();
-      normalRelation.setName(otherMethod.getName() +
+      normalRelation.setLabel(otherMethod.getName() +
           (otherMethod.asSingleRelationMethod().isOptRelationMethod() ? "?" : ""));
       normalRelation.setDumpNode(targetNode);
       node.addDumpRelation(normalRelation);
@@ -295,7 +295,7 @@ aspect Transform {
     // -- listRelation --
     Iterable<?> targetList = (Iterable<?>) otherMethod.getMethod().invoke(obj);
     DumpListRelation listRelation = new DumpListRelation();
-    listRelation.setName(otherMethod.getName());
+    listRelation.setLabel(otherMethod.getName());
     node.addDumpRelation(listRelation);
 
     int index = -1;
@@ -367,7 +367,7 @@ aspect Transform {
         }
       }
       if (token != null) {
-        token.setName(otherMethod.getName());
+        token.setLabel(otherMethod.getName());
         token.setComputed(otherMethod.asTokenMethod().isAttributeMethod());
         node.addDumpToken(token);
       }
@@ -405,52 +405,38 @@ aspect Transform {
   }
 
   // === RelationStyle ===
-  RelationStyle DumpNormalChildNode.createDefaultStyle() {
-    return new RelationStyle().setLabel(getName());
+  interface RelationStylable<SELF> {
+    default RelationStyle createDefaultStyle() {
+      return new RelationStyle().setLabel(initialLabel());
+    }
+    default void applyStyle(RelationStyleDefinition relationStyleDefinition) {
+      RelationStyle style = createDefaultStyle();
+      relationStyleDefinition.style(containingDumpNode().getObject(), getDumpNode().getObject(), style);
+      setLabel(style.getLabel());
+      setTextColor(style.getTextColor());
+      setLineColor(style.getLineColor());
+    }
+    String initialLabel();
+    DumpNode containingDumpNode();
+    DumpNode getDumpNode();
+    SELF setLabel(String name);
+    SELF setTextColor(String textColor);
+    SELF setLineColor(String lineColor);
   }
+  DumpNormalChildNode implements RelationStylable<DumpNormalChildNode>;
+  syn String DumpNormalChildNode.initialLabel() = getLabel();
 
-  RelationStyle InnerDumpNode.createDefaultStyle() {
-    return new RelationStyle().setLabel(containingDumpListChildNode().getName());
-  }
+  InnerDumpNode implements RelationStylable<InnerDumpNode>;
+  syn String InnerDumpNode.initialLabel() = containingDumpListChildNode().getLabel();
 
-  RelationStyle DumpNormalRelation.createDefaultStyle() {
-    return new RelationStyle().setLabel(getName());
-  }
+  DumpNormalRelation implements RelationStylable<DumpNormalRelation>;
+  syn String DumpNormalRelation.initialLabel() = getLabel();
 
-  RelationStyle InnerRelationDumpNode.createDefaultStyle() {
-    return new RelationStyle().setLabel(containingDumpListRelation().getName());
-  }
+  InnerRelationDumpNode implements RelationStylable<InnerRelationDumpNode>;
+  syn String InnerRelationDumpNode.initialLabel() = containingDumpListRelation().getLabel();
 
-  private void DumpAst.applyStyle(DumpNormalChildNode node) {
-    RelationStyle style = node.createDefaultStyle();
-    getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(),
-        node.getDumpNode().getObject(), node.getName(), style);
-    node.setName(style.getLabel());
-    node.setTextColor(style.getTextColor());
-  }
-
-  private void DumpAst.applyStyle(InnerDumpNode node) {
-    RelationStyle style = node.createDefaultStyle();
-    getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(),
-        node.getDumpNode().getObject(), node.containingDumpListChildNode().getName(), style);
-    node.setLabel(style.getLabel());
-    node.setTextColor(style.getTextColor());
-  }
-
-  private void DumpAst.applyStyle(DumpNormalRelation node) {
-    RelationStyle style = node.createDefaultStyle();
-    getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(),
-        node.getDumpNode().getObject(), node.getName(), style);
-    node.setName(style.getLabel());
-    node.setTextColor(style.getTextColor());
-  }
-
-  private void DumpAst.applyStyle(InnerRelationDumpNode node) {
-    RelationStyle style = node.createDefaultStyle();
-    getPrintConfig().getRelationStyleDefinition().style(node.containingDumpNode().getObject(),
-        node.getDumpNode().getObject(), node.containingDumpListRelation().getName(), style);
-    node.setLabel(style.getLabel());
-    node.setTextColor(style.getTextColor());
+  private void DumpAst.applyStyle(RelationStylable<?> stylable) {
+    stylable.applyStyle(getPrintConfig().getRelationStyleDefinition());
   }
 
   // --- isTypeEnabled ---
diff --git a/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java b/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java
index e3a7265fb4948038735661681fab2edc67a8fd31..89d8cf4057224d9385fc48f656d5bbfe2890a4ab 100644
--- a/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java
+++ b/dumpAst.base/src/main/java/de/tudresden/inf/st/jastadd/dumpAst/ast/DumpBuilder.java
@@ -39,7 +39,7 @@ public class DumpBuilder {
     dumpAst.getPrintConfig().setScale(1);
     dumpAst.getPrintConfig().setVersion(readVersion());
     dumpAst.getPrintConfig().setNodeStyleDefinition((node, style) -> {});
-    dumpAst.getPrintConfig().setRelationStyleDefinition((sourceNode, targetNode, context, style) -> {});
+    dumpAst.getPrintConfig().setRelationStyleDefinition((sourceNode, targetNode, style) -> {});
   }
 
   private DumpBuilder thisWithResetBuilt() {
diff --git a/dumpAst.base/src/main/resources/RelationStyle.mustache b/dumpAst.base/src/main/resources/RelationStyle.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..b48a25121e6fa8e4d31d1eaecbb29bb5874e444f
--- /dev/null
+++ b/dumpAst.base/src/main/resources/RelationStyle.mustache
@@ -0,0 +1 @@
+{{#TextColor}}#text:{{{TextColor}}}{{/TextColor}}{{#LineColor}}{{#TextColor}};{{/TextColor}}{{^TextColor}}#{{/TextColor}}line:{{{LineColor}}}{{/LineColor}}
\ No newline at end of file
diff --git a/dumpAst.base/src/main/resources/dumpAst.mustache b/dumpAst.base/src/main/resources/dumpAst.mustache
index 80010c0882ada38aafc77e43b4f2a2f79dd091ce..350e26a5047cfb25d60fae4bb654b5790da62473 100644
--- a/dumpAst.base/src/main/resources/dumpAst.mustache
+++ b/dumpAst.base/src/main/resources/dumpAst.mustache
@@ -11,60 +11,60 @@ skinparam object<<NTA>> {
 hide <<NTA>> stereotype
 
 {{#PrintConfig}}
-scale {{{scale}}}
+scale {{{Scale}}}
   {{#Headers}}
-{{{value}}}
+{{{Value}}}
   {{/Headers}}
 {{/PrintConfig}}
 
 {{#DumpNodes}}
-  {{^invisible}}
+  {{^Invisible}}
     {{#isNull}}
-object "null" as {{{name}}}<<null>>
+object "null" as {{{Name}}}<<null>>
     {{/isNull}}
     {{#isEmpty}}
-object "[]" as {{{name}}}<<null>>
+object "[]" as {{{Name}}}<<null>>
     {{/isEmpty}}
     {{#isAstNode}}
-object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroundColor}}#{{{backgroundColor}}}{{/backgroundColor}} {
+object "{{{labelAndTextColor}}}" as {{{Name}}} {{{stereotypeList}}} {{#BackgroundColor}}#{{{BackgroundColor}}}{{/BackgroundColor}} {
       {{#DumpTokens}}
         {{#isDumpValueToken}}
-  {{{label}}} = {{{value}}}
+  {{{label}}} = {{{Value}}}
         {{/isDumpValueToken}}
       {{/DumpTokens}}
 }
     {{/isAstNode}}
-  {{/invisible}}
+  {{/Invisible}}
 {{/DumpNodes}}
 
 {{#DumpNodes}}
   {{#DumpTokens}}
-    {{^invisible}}
+    {{^Invisible}}
       {{#isList}}
         {{#InnerRelationDumpNode}}
           {{#bothVisible}}
-{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} .[#black{{#Computed}},#{{{computedColor}}}{{/Computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}}
           {{/bothVisible}}
         {{/InnerRelationDumpNode}}
       {{/isList}}
       {{^isList}}
         {{^isDumpValueToken}}
-{{{outerNodeName}}} .[#black{{#computed}},#{{{computedColor}}}{{/computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} .[#black{{#Computed}},#{{{computedColor}}}{{/Computed}}{{#innerNotNullOrEmpty}},norank{{/innerNotNullOrEmpty}}].> {{{innerNodeName}}} : {{{label}}}
         {{/isDumpValueToken}}
       {{/isList}}
-    {{/invisible}}
+    {{/Invisible}}
   {{/DumpTokens}}
   {{#DumpChildNodes}}
     {{#isList}}
       {{#InnerDumpNodes}}
         {{#bothVisible}}
-{{{outerNodeName}}} *-{{#computed}}[#{{{computedColor}}}]{{/computed}}- {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} *-{{#Computed}}[#{{{computedColor}}}]{{/Computed}}- {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}}
         {{/bothVisible}}
       {{/InnerDumpNodes}}
     {{/isList}}
     {{^isList}}
       {{#bothVisible}}
-{{{outerNodeName}}} *-{{#computed}}[#{{{computedColor}}}]{{/computed}}- {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} *-{{#Computed}}[#{{{computedColor}}}]{{/Computed}}- {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}}
       {{/bothVisible}}
     {{/isList}}
   {{/DumpChildNodes}}
@@ -72,36 +72,36 @@ object "{{{labelAndTextColor}}}" as {{{name}}} {{{stereotypeList}}} {{#backgroun
     {{#isList}}
       {{#InnerRelationDumpNode}}
         {{#bothVisible}}
-{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} {{#Bidirectional}}<{{/Bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}}
         {{/bothVisible}}
       {{/InnerRelationDumpNode}}
     {{/isList}}
     {{^isList}}
       {{#bothVisible}}
-{{{outerNodeName}}} {{#bidirectional}}<{{/bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} : {{{label}}}
+{{{outerNodeName}}} {{#Bidirectional}}<{{/Bidirectional}}-{{#innerNotNullOrEmpty}}[norank]{{/innerNotNullOrEmpty}}-> {{{innerNodeName}}} {{#needRelationStyling}}{{>RelationStyle}}{{/needRelationStyling}} : {{{label}}}
       {{/bothVisible}}
     {{/isList}}
   {{/DumpRelations}}
-  {{^invisible}}
+  {{^Invisible}}
     {{#InvisiblePath}}
       {{#InnerRelationDumpNode}}
 {{{outerNodeName}}} o.. {{{innerNodeName}}}
       {{/InnerRelationDumpNode}}
     {{/InvisiblePath}}
-  {{/invisible}}
-  {{#PrintConfig}}{{#orderChildren}}
+  {{/Invisible}}
+  {{#PrintConfig}}{{#OrderChildren}}
       {{#myChildren}}
           {{#hasSuccessor}}
-{{{name}}} -[hidden]right-> {{#successor}}{{{name}}}{{/successor}}
+{{{Name}}} -[hidden]right-> {{#successor}}{{{Name}}}{{/successor}}
           {{/hasSuccessor}}
       {{/myChildren}}
-  {{/orderChildren}}{{/PrintConfig}}
+  {{/OrderChildren}}{{/PrintConfig}}
 {{/DumpNodes}}
 {{#PrintConfig}}
   {{#debug}}
 legend right
   %date()
-  dumpAst: {{{version}}}
+  dumpAst: {{{Version}}}
   plantuml: %version()
 endlegend
   {{/debug}}
diff --git a/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java b/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java
index 10e3f6afd2bd043499bd9788f4168cceb98803b7..cf3ce5b068a919cafe5604cc3a816dcb609901d1 100644
--- a/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java
+++ b/dumpAst.prototyping/src/main/java/de/tudresden/inf/st/jastadd/featureTest/FeatureTestMain.java
@@ -22,6 +22,7 @@ public class FeatureTestMain {
     root.setName("Root1");
     A a = new A().setName("A2");
     a.setB(new B().setName("B2.1"));
+    a.setD(new D());
 //    a.setMyC(new C().setName("C2.1"));
     B b1 = new B().setName("B3").setOtherValue("some long text");
 //    C c = new C().setName("C4");
@@ -48,9 +49,9 @@ public class FeatureTestMain {
         .enableDebug()
         .customPreamble("title My fancy title")
         .includeChild((parentNode, childNode, contextName) -> {
-          if (parentNode instanceof A && ((A) parentNode).getName().equals("A2")) {
-            return false;
-          }
+//          if (parentNode instanceof A && ((A) parentNode).getName().equals("A2")) {
+//            return false;
+//          }
           if (parentNode instanceof Root && childNode instanceof B) {
             return !"B3".equals(((B) childNode).getName());
           }
@@ -72,11 +73,12 @@ public class FeatureTestMain {
           }
         })
         .skinParam(SkinParamBooleanSetting.Shadowing, false)
-        .relationStyle((source, target, context, style) -> {
-          if (context.equals("ManyA")) {
+        .relationStyle((source, target, style) -> {
+          if (style.getLabel().equals("ManyA")) {
             style.setLabel("ManyA of " + ((Nameable) source).getName());
-          } else if (context.equals("OneA") || context.equals("MaybeC")) {
+          } else if (style.getLabel().equals("OneA") || style.getLabel().equals("MaybeC?")) {
             style.setTextColor("red");
+            style.setLineColor("green");
           }
         })
         .<ASTNode<?>>nodeStyle((node, style) -> {
diff --git a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestComplex.java b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestRegression.java
similarity index 62%
rename from dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestComplex.java
rename to dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestRegression.java
index 574ec066d9d04d22bfc0f3662058f0960c516d20..a7a35cdf0200dd9726bb4f8f79e7ecda1c544a30 100644
--- a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestComplex.java
+++ b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestRegression.java
@@ -6,22 +6,28 @@ import org.jastadd.testDumper.ast.DropOffLocation;
 import org.jastadd.testDumper.ast.Orientation;
 import org.jastadd.testDumper.ast.Position;
 import org.jastadd.testDumper.ast.Size;
+import org.junit.jupiter.api.Assertions;
 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 static de.tudresden.inf.st.jastadd.testDumper.TestUtils.*;
 import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 /**
- * More complex test cases.
+ * Regression test cases.
  *
  * @author rschoene - Initial contribution
  */
-public class TestComplex {
+public class TestRegression {
 
   @Test
-  public void testRegressionIssue16() throws TransformationException {
+  public void regressionIssue16() throws TransformationException {
     DropOffLocation location = new DropOffLocation();
     location.setName(ROOT_NAME);
     location.setPosition(new Position(T1_NAME, 1, 2, 3));
@@ -35,4 +41,11 @@ public class TestComplex {
         entry("Y", 2.0),
         entry("Z", 3.0));
   }
+
+  @Test
+  public void regressionNoNewlineForRelationStyleMustache() throws IOException {
+    Path path = Paths.get("..", "dumpAst.base", "src", "main", "resources", "RelationStyle.mustache");
+    List<String> lines = Files.readAllLines(path);
+    assertEquals(1, lines.size(), "Ensure no trailing newline in RelationStyle.mustache");
+  }
 }
diff --git a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java
index 9bd634b20ca1c3d231194c3801595678a00a9333..5246c9f332a82b94326598bbf27cc92bb1f65b42 100644
--- a/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java
+++ b/dumpAst.tests/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java
@@ -93,7 +93,7 @@ public class TestUtils {
 
   public static final Function<DumpNode, String> NAME_EXTRACTOR = node -> {
     for (DumpToken dumpToken : node.getDumpTokenList()) {
-      if (dumpToken.getName().equals("Name")) {
+      if (dumpToken.getLabel().equals("Name")) {
         return dumpToken.asDumpValueToken().getValue().toString();
       }
     }
@@ -156,7 +156,7 @@ public class TestUtils {
         // then it is a DumpNormalChildNode
         DumpNode target = ((DumpNormalChildNode) dumpChildNode).getDumpNode();
         if (target != null && !target.getInvisible()) {
-          result.put(dumpChildNode.getName(), target);
+          result.put(dumpChildNode.getLabel(), target);
         }
       }
     }
@@ -170,7 +170,7 @@ public class TestUtils {
         // then it is a DumpListChildNode
         ((DumpListChildNode) dumpChildNode).getInnerDumpNodeList().forEach(inner -> {
           if (inner.getDumpNode() != null && !inner.getDumpNode().getInvisible()) {
-            result.computeIfAbsent(dumpChildNode.getName(), key -> new ArrayList<>()).add(inner.getDumpNode());
+            result.computeIfAbsent(dumpChildNode.getLabel(), key -> new ArrayList<>()).add(inner.getDumpNode());
           }
         });
       }
@@ -185,7 +185,7 @@ public class TestUtils {
         // then it is a DumpNormalRelation
         DumpNode target = ((DumpNormalRelation) dumpRelation).getDumpNode();
         if (!target.getInvisible()) {
-          result.put(dumpRelation.getName(), target);
+          result.put(dumpRelation.getLabel(), target);
         }
       }
     }
@@ -199,7 +199,7 @@ public class TestUtils {
         // then it is a DumpListRelation
         ((DumpListRelation) dumpRelation).getInnerRelationDumpNodeList().forEach(inner -> {
           if (!inner.getDumpNode().getInvisible()) {
-            result.computeIfAbsent(dumpRelation.getName(), key -> new ArrayList<>()).add(inner.getDumpNode());
+            result.computeIfAbsent(dumpRelation.getLabel(), key -> new ArrayList<>()).add(inner.getDumpNode());
           }
         });
       }
@@ -214,7 +214,7 @@ public class TestUtils {
         // then it is a DumpReferenceToken
         DumpNode target = ((DumpReferenceToken) dumpToken).getValue();
         if (!target.getInvisible()) {
-          result.put(dumpToken.getName(), target);
+          result.put(dumpToken.getLabel(), target);
         }
       }
     }
@@ -228,7 +228,7 @@ public class TestUtils {
         // then it is a DumpReferenceListToken
         ((DumpReferenceListToken) dumpToken).getInnerRelationDumpNodeList().forEach(inner -> {
           if (!inner.getDumpNode().getInvisible()) {
-            result.computeIfAbsent(dumpToken.getName(), key -> new ArrayList<>()).add(inner.getDumpNode());
+            result.computeIfAbsent(dumpToken.getLabel(), key -> new ArrayList<>()).add(inner.getDumpNode());
           }
         });
       }
@@ -242,7 +242,7 @@ public class TestUtils {
       if (dumpToken.isDumpValueToken()) {
         // then it is a DumpValueToken
         DumpValueToken dumpValueToken = (DumpValueToken) dumpToken;
-        result.put(dumpValueToken.getName(), dumpValueToken.getValue());
+        result.put(dumpValueToken.getLabel(), dumpValueToken.getValue());
       }
     }
     return result;
diff --git a/pages/docs/using.md b/pages/docs/using.md
index 04472f13a6818e4b67fb26fad4bd6df36d10c6b0..26cd6c0c6c3c60d6bb7e08084f945e97b7c93290 100644
--- a/pages/docs/using.md
+++ b/pages/docs/using.md
@@ -27,15 +27,20 @@ public class Main {
           }
           return !contextName.equals("EndEffector");
         })
-        .style((node, style) -> {
+        .nodeStyle((node, style) -> {
           style.useSimpleName();  // (4)
           style.setBackgroundColor(node.size() > 30 ? "blue" : "white");  // (5)
         })
-        .skinParam(SkinParamBooleanSetting.Shadowing, false);  // (6)
-    builder.dumpAsPng(Paths.get("featureTest.png"));  // (7)
-    builder.dumpAsSVG(Paths.get("featureTest.svg"));  // (8)
+        .relationStyle((source, target, style) -> {
+          if (style.getLabel().equals("EndEffector")) {
+            style.setLabel("");  // (6)
+          }
+        })
+        .skinParam(SkinParamBooleanSetting.Shadowing, false);  // (7)
+    builder.dumpAsPng(Paths.get("featureTest.png"));  // (8)
+    builder.dumpAsSVG(Paths.get("featureTest.svg"));  // (9)
     OutputStream os = getMyOutputStream();
-    builder.dumpAsPNG(os);  // (9)
+    builder.dumpAsPNG(os);  // (10)
   }
 }
 ```
@@ -51,9 +56,10 @@ The steps in detail:
 - (1) In the beginning, your model is somehow constructed and changed. This is indicated with the method `createModel`.
 - (2) The first call is always `Dumper.read()` to which the (part of the) AST is provided as an argument. It returns an object of type [DumpBuilder](../ragdoc/#/type/DumpBuilder). With this object, the output can be changed.
 - (3) [Optional] You can only include nodes of certain types by using `includeChild` and passing a lambda function, which is called for every node and should return `true` if the `childNode` shall be included in the output. It defaults to returning `true` for every node. Here, all children of a `Robot` node (except if the name of the robot is `"Robot2"`) and all children of the context named `"EndEffector"` are excluded.
-- (4) and (5) [Optional] To style a node, the `style` is used. It accepts a lambda function, in which the style of every node can be customized by calling methods on the given `Style` object, e.g. setting the name (5) or background color (6). The default name is to use the class name along with the hashcode of the object (`node == null ? "null" : node.getClass().getSimpleName() + "@" + Integer.toHexString(node.hashCode())`).
-- (6) [Optional] There are a few ways to style the output in general through [SkinParam](https://plantuml.com/de/skinparam). Not all of those parameters are supported; see `SkinParamBooleanSetting` and `SkinParamStringSetting`.
-- (7), (8) and (9) To create an output image, use `dumpAsPng` for PNG (`dumpAsSVG` for SVG). Those methods do not return the builder object, as they produce an output. They potentially throw two kinds of exception: `IOException` (when the file could not be written) and `TransformationException` (when the AST could not be processed). As shown here, the builder object must be stored in a variable to create multiple outputs. Alternatively to a file, the result can be written to a given `OutputStream` (9).
+- (4) and (5) [Optional] To style a node, the method `nodeStyle` is used. It accepts a lambda function, in which the style of every node can be customized by calling methods on the given `Style` object, e.g. setting the name (5) or background color (6). The default name is to use the class name along with the hashcode of the object (`node == null ? "null" : node.getClass().getSimpleName() + "@" + Integer.toHexString(node.hashCode())`).
+- (6) [Optional] To style a relation, the method `relationStyle` is used. It is used similar to `nodeStyle`, but is called with source and target node of a relation (containment and non-containment). Note, that (a) the default label can be retrieved with `style.getLabel()` and (b) indices are always appended to the set label.
+- (7) [Optional] There are a few ways to style the output in general through [SkinParam](https://plantuml.com/de/skinparam). Not all of those parameters are supported; see `SkinParamBooleanSetting` and `SkinParamStringSetting`.
+- (8), (9) and (10) To create an output image, use `dumpAsPng` for PNG (`dumpAsSVG` for SVG). Those methods do not return the builder object, as they produce an output. They potentially throw two kinds of exception: `IOException` (when the file could not be written) and `TransformationException` (when the AST could not be processed). As shown here, the builder object must be stored in a variable to create multiple outputs. Alternatively to a file, the result can be written to a given `OutputStream` (10).
 
 To summarise the required steps: Specify the AST to read in, configure the output, and write ("dump") the output.
 For more configuration options, please consult the [API Docs of DumpBuilder](../ragdoc/#/type/DumpBuilder).