diff --git a/src/jastadd/ast/CollectionAttributes.jrag b/src/jastadd/ast/CollectionAttributes.jrag
index 306084c6a43a2dd35174b0dcc9b9402988ca6c14..545f871930fb0cfc56b8335ccfd680babd59b2c9 100644
--- a/src/jastadd/ast/CollectionAttributes.jrag
+++ b/src/jastadd/ast/CollectionAttributes.jrag
@@ -36,8 +36,12 @@ aspect CollectionAttributes {
 
   eq CollDecl.isCollection() = true;
 
+  /** @return the type name of the collection root node */
   syn String CollDecl.rootType() = root().name();
 
+  /** @return the type name of the collection root node */
+  syn String CollEq.rootType() = decl().rootType();
+
   /** @return the return type of the collection attribute */
   syn String CollEq.getType() = decl().getType();
 
@@ -117,6 +121,7 @@ aspect CollectionAttributes {
   }
 
   syn TypeDecl AttrDecl.root() = grammar().root();
+
   eq CollDecl.root() = root != null ? grammar().lookup(root) : super.root();
 
   // Only used by circular collection attributes.
diff --git a/src/jastadd/ast/JragCodeGen.jrag b/src/jastadd/ast/JragCodeGen.jrag
index 06c311ac361b3feb86747ff75e0071fa703569c7..eaf12b6eb7199fa55fe054f7fe844e3ed9cfd49c 100644
--- a/src/jastadd/ast/JragCodeGen.jrag
+++ b/src/jastadd/ast/JragCodeGen.jrag
@@ -220,17 +220,16 @@ aspect JragCodeGen {
     if (config().lazyMaps()) {
       if (!isCircular()) {
         if (getNumParameter() != 0 && config().visitCheckEnabled() && config().rewriteEnabled()) {
-          sb.append("if (" + signature() + "_visited == null) " + signature()
-              + "_visited = " + config().createDefaultMap() + ";\n");
-        }
-        else if (getNumParameter() != 0 && config().visitCheckEnabled()) {
-          sb.append("if (" + signature() + "_visited == null) " + signature()
-              + "_visited = " + config().createDefaultSet() + ";\n");
+          sb.append(String.format("if (%s_visited == null) %s_visited = %s;\n",
+              signature(), signature(), config().createDefaultMap()));
+        } else if (getNumParameter() != 0 && config().visitCheckEnabled()) {
+          sb.append(String.format("if (%s_visited == null) %s_visited = %s;\n",
+              signature(), signature(), config().createDefaultSet()));
         }
       }
       if (getNumParameter() != 0 && (isLazy() || isCircular())) {
-        sb.append("if (" + signature() + "_values == null) " + signature()
-            + "_values = " + config().createDefaultMap() + ";\n");
+        sb.append(String.format("if (%s_values == null) %s_values = %s;\n",
+            signature(), signature(), config().createDefaultMap()));
       }
     }
     return sb.toString();
@@ -257,7 +256,9 @@ aspect JragCodeGen {
    * @return {@code true} if the attribute is declared as NTA in the aspect file
    */
   syn boolean AttrDecl.declaredNTA() = false;
+
   eq SynDecl.declaredNTA() = getNTA();
+
   eq InhDecl.declaredNTA() = getNTA();
 
   public static String ASTNode.boxedType(String type) {
@@ -413,7 +414,7 @@ aspect JragCodeGen {
   public boolean TypeDecl.hasLazySynEqFor(AttrDecl attr) {
     if (attr instanceof SynDecl) {
       SynEq synEq = lookupSynEq(attr.signature());
-      return synEq != null && (synEq.decl().isLazy() || synEq.decl().isCircular()) ;
+      return synEq != null && (synEq.decl().isLazy() || synEq.decl().isCircular());
     }
     return false;
   }
@@ -663,7 +664,7 @@ aspect JragCodeGen {
             + " was affected by a bug causing the equation value to be discarded! "
             + "(fixed since version 2.1.11)");
       }
-      String attrName = getName().substring(3); // remove get
+      String attrName = getName().substring(3);
       if (comp.name().equals(attrName) && comp instanceof AggregateComponentNTA
           || attrName.equals(comp.name() + "Opt") && comp instanceof OptionalComponentNTA
           || attrName.equals(comp.name() + "List") && comp instanceof ListComponentNTA) {
diff --git a/src/template/ast/Circular.tt b/src/template/ast/Circular.tt
index 30c338cc03abab63a1edc9c8d35ecc22d7d6a24b..e51626b118a85a1cabb9048343b42d37f10eced7 100644
--- a/src/template/ast/Circular.tt
+++ b/src/template/ast/Circular.tt
@@ -45,7 +45,7 @@ $if(#isCollection)
       while (_node != null && !(_node instanceof #rootType)) {
         _node = _node.getParent();
       }
-      $include(collDebugCheck)
+      $include(CollDecl.collDebugCheck)
       #rootType root = (#rootType) _node;
       if (root.collecting_contributors_#collectionId) {
         throw new RuntimeException("Circularity during survey phase");
diff --git a/src/template/ast/Collections.tt b/src/template/ast/Collections.tt
index df3cb9df9572588461e0e1f5b4c63380e9bf9664..afb127437f5f74e96cca289796ca98d6c43b3ab6 100644
--- a/src/template/ast/Collections.tt
+++ b/src/template/ast/Collections.tt
@@ -25,11 +25,11 @@
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-collDebugCheck [[
+CollDecl.collDebugCheck [[
 $if(DebugMode)
 if (node == null) {
   throw new RuntimeException(
-      "Trying to evaluate collection attribute in subtree not attached to main tree");
+      "Trying to evaluate collection attribute #getTarget.#getName() in subtree not attached to main tree.");
 }
 $endif
 ]]
@@ -41,7 +41,7 @@ CollDecl.computeMethod:onePhase [[
     while (node != null && !(node instanceof #rootType)) {
       node = node.getParent();
     }
-    $include(collDebugCheck)
+    $include(CollDecl.collDebugCheck)
     #rootType root = (#rootType) node;
     root.survey_#collectionId();
     if (#(signature)_value == null) {
@@ -58,7 +58,7 @@ CollDecl.computeMethod:twoPhase [[
     while (node != null && !(node instanceof #rootType)) {
       node = node.getParent();
     }
-    $include(collDebugCheck)
+    $include(CollDecl.collDebugCheck)
     #rootType root = (#rootType) node;
     root.survey_#collectionId();
     #getType _computedValue = $BottomValue;
@@ -71,7 +71,7 @@ CollDecl.computeMethod:twoPhase [[
   }
 ]]
 
-CollEq.collectContributors:onePhase = [[
+CollEq.collectContributors:onePhase [[
     // #declaredat
 $if(HasCondition)
     if (#getCondition) {
@@ -85,13 +85,12 @@ $endif
 CollEq.contribution:onePhase [[
 $if(#iterableTarget)
 for (#getTargetName target : (Iterable<? extends #getTargetName>) (#getReference)) {
-  if (target != null) {
-    if (target.#(signature)_value == null) {
-      target.#(signature)_value = $BottomValue;
-    }
-    #getType collection = target.#(signature)_value;
-    $include(CollEq.addValueToCollection)
+  $include(CollEq.targetDebugCheck)
+  if (target.#(signature)_value == null) {
+    target.#(signature)_value = $BottomValue;
   }
+  #getType collection = target.#(signature)_value;
+  $include(CollEq.addValueToCollection)
 }
 $else
 {
@@ -103,19 +102,18 @@ $if(#implicitTarget)
   $include(CollEq.addValueToCollection)
 $else
   #getTargetName target = #getReference;
-  if (target != null) {
-    if (target.#(signature)_value == null) {
-      target.#(signature)_value = $BottomValue;
-    }
-    #getType collection = target.#(signature)_value;
-    $include(CollEq.addValueToCollection)
+  $include(CollEq.targetDebugCheck)
+  if (target.#(signature)_value == null) {
+    target.#(signature)_value = $BottomValue;
   }
+  #getType collection = target.#(signature)_value;
+  $include(CollEq.addValueToCollection)
 $endif
 }
 $endif
 ]]
 
-CollEq.collectContributors:twoPhase = [[
+CollEq.collectContributors:twoPhase [[
     // #declaredat
 $if(HasCondition)
     if (#getCondition) {
@@ -129,41 +127,62 @@ $endif
 CollEq.contribution:twoPhase [[
 $if(#iterableTarget)
 for (#getTargetName target : (Iterable<? extends #getTargetName>) (#getReference)) {
-  if (target != null) {
-    java.util.Set<$ASTNode> contributors = _map.get(target);
-    if (contributors == null) {
-      contributors = new java.util.HashSet<$ASTNode>();
-      _map.put(($ASTNode) target, contributors);
-    }
-    contributors.add(this);
+  $include(CollEq.targetDebugCheck)
+  java.util.Set<$ASTNode> contributors = _map.get(target);
+  if (contributors == null) {
+    contributors = new java.util.HashSet<$ASTNode>();
+    _map.put(($ASTNode) target, contributors);
   }
+  contributors.add(this);
 }
 $else
 {
 $if(#implicitTarget)
-  if (_root != null) {
-    java.util.Set<$ASTNode> contributors = _map.get(_root);
-    if (contributors == null) {
-      contributors = new java.util.HashSet<$ASTNode>();
-      _map.put(($ASTNode) _root, contributors);
-    }
-    contributors.add(this);
+  java.util.Set<$ASTNode> contributors = _map.get(_root);
+  if (contributors == null) {
+    contributors = new java.util.HashSet<$ASTNode>();
+    _map.put(($ASTNode) _root, contributors);
   }
+  contributors.add(this);
 $else
   #getTargetName target = (#getTargetName) (#getReference);
-  if (target != null) {
-    java.util.Set<$ASTNode> contributors = _map.get(target);
-    if (contributors == null) {
-      contributors = new java.util.HashSet<$ASTNode>();
-      _map.put(($ASTNode) target, contributors);
-    }
-    contributors.add(this);
+  $include(CollEq.targetDebugCheck)
+  java.util.Set<$ASTNode> contributors = _map.get(target);
+  if (contributors == null) {
+    contributors = new java.util.HashSet<$ASTNode>();
+    _map.put(($ASTNode) target, contributors);
   }
+  contributors.add(this);
 $endif
 }
 $endif
 ]]
 
+CollEq.targetDebugCheck [[
+$if(DebugMode)
+ASTNode _targetRoot = target;
+ASTNode _targetParent = target;
+while (_targetParent != null) {
+  _targetParent = _targetParent.getParent();
+  if (_targetParent instanceof #rootType) {
+    _targetRoot = _targetParent;
+  }
+}
+ASTNode _sourceRoot = _root;
+ASTNode _sourceParent = _root;
+while (_sourceParent != null) {
+  _sourceParent = _sourceParent.getParent();
+  if (_sourceParent instanceof #rootType) {
+    _sourceRoot = _sourceParent;
+  }
+}
+if (_targetRoot != _sourceRoot) {
+  throw new RuntimeException("Contribution source and target do not share a common collection "
+      + "root node for collection attribute #getTargetName.#getTargetAttributeName().");
+}
+$endif
+]]
+
 CollDecl.collectContributors:header [[
 $if(#onePhase)
   protected void collect_contributors_#collectionId(#rootType _root) {
@@ -188,7 +207,7 @@ $endif
   }
 ]]
 
-CollDecl.contributeTo:default = [[
+CollDecl.contributeTo:default [[
   protected void contributeTo_#(signature)(#getType collection) {
   }
 ]]
@@ -255,7 +274,7 @@ $endif
   }
 ]]
 
-Collection.flush = [[
+Collection.flush [[
 $if(#onePhase)
 collect_contributors_#collectionId = false;
 $else