diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd
index 569d61b473639b9ef0ad2146b96543ab66109d5a..b285919da1c5cdb9a04de7ec16863e06c330c861 100644
--- a/src/main/jastadd/Backend.jadd
+++ b/src/main/jastadd/Backend.jadd
@@ -187,7 +187,31 @@ aspect BackendDirectedAPI {
 
   public void ManyRelationComponent.generateDirectedAPI(StringBuilder sb) {
     // Get
-    generateGetMany(sb);
+    // getXs
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+    sb.append(".get" + nameCapitalized() + "s() {\n");
+    sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n");
+    sb.append(ind(1) + "}\n");
+
+    // getXList
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+    sb.append(".get" + nameCapitalized() + "List() {\n");
+    sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n");
+    // resolve the entire list
+    if (resolverHelper) {
+      sb.append(ind(2) + "if (l != null) {\n");
+        sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
+          sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
+          sb.append(ind(4) + "if (element.unresolved()) {\n");
+            sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n");
+            sb.append(ind(5) + "l.set(i, resolvedElement);\n");
+          sb.append(ind(4) + "}\n");
+        sb.append(ind(3) + "}\n");
+        sb.append(ind(3) + "set" + getImplAttributeName() + "(l);\n");
+      sb.append(ind(2) + "}\n");
+    }
+    sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n");
+    sb.append(ind(1) + "}\n");
 
     // Add
     sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
@@ -237,36 +261,6 @@ aspect BackendDirectedAPI {
     sb.append(ind(2) + "set" + nameCapitalized() + "(null);\n");
     sb.append(ind(1) + "}\n");
   }
-
-  public void RelationComponent.generateGetMany(StringBuilder sb) {
-    // getXs
-    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
-    sb.append(".get" + nameCapitalized() + "s() {\n");
-    sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n");
-    sb.append(ind(1) + "}\n");
-
-    // getXList
-    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
-    sb.append(".get" + nameCapitalized() + "List() {\n");
-    sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get"
-      + getImplAttributeName() + "();\n");
-    // resolve the entire list
-    if (resolverHelper) {
-      sb.append(ind(2) + "int removedElements = 0;\n");
-      sb.append(ind(2) + "if (l != null) {\n");
-        sb.append(ind(3) + "for (int i = 0; i < l.size() - removedElements; i++) {\n");
-          sb.append(ind(4) + "if (get" + getImplAttributeName() + "().get(i) != null && get" + getImplAttributeName() + "().get(i).unresolved()) {\n");
-            sb.append(ind(5) + ofTypeDecl() + " element = l.remove(i);\n");
-            sb.append(ind(5) + "add" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i));\n");
-            sb.append(ind(5) + "i--; // go back an index, because we removed an element\n");
-            sb.append(ind(5) + "removedElements++; // no need to iterate over the removed elements again\n");
-          sb.append(ind(4) + "}\n");
-        sb.append(ind(3) + "}\n");
-      sb.append(ind(2) + "}\n");
-    }
-    sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n");
-    sb.append(ind(1) + "}\n");
-  }
 }
 
 aspect BackendBidirectionalAPI {
@@ -321,11 +315,7 @@ aspect BackendBidirectionalAPI {
       sb.append(ind(2) + "assertNotNull(o);\n");
     }
     // unset the old opposite
-//    if (resolverHelper) {
-//      sb.append(ind(2) + "if (!o.unresolved() && get" + getImplAttributeName() + "() != null) {\n");
-//    } else {
-      sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null) {\n");
-//    }
+    sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null) {\n");
     sb.append(ind(3) + "get" + getImplAttributeName() + "().set" + otherSide().getImplAttributeName() + "(null);\n");
     sb.append(ind(2) + "}\n");
     if (resolverHelper) {
@@ -365,7 +355,39 @@ aspect BackendBidirectionalAPI {
 
   public void RelationComponent.generateBiManyMany(StringBuilder sb) {
     // Get
-    generateGetMany(sb);
+    // getXs
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+    sb.append(".get" + nameCapitalized() + "s() {\n");
+    sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n");
+    sb.append(ind(1) + "}\n");
+
+    // getXList
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+    sb.append(".get" + nameCapitalized() + "List() {\n");
+    sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n");
+    // resolve the entire list
+    if (resolverHelper) {
+      sb.append(ind(2) + "if (l != null) {\n");
+        sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
+          sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
+          sb.append(ind(4) + "if (element.unresolved()) {\n");
+            sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n");
+            sb.append(ind(5) + "if (resolvedElement != null) {\n");
+              sb.append(ind(6) + ASTNode.listClass + "<" + toTypeDecl() + "> otherList = resolvedElement.get" + getImplAttributeName() + "();\n");
+              sb.append(ind(6) + "if (otherList == null) {\n");
+                sb.append(ind(7) + "otherList = new ArrayList<>();\n");
+              sb.append(ind(6) + "}\n");
+              sb.append(ind(6) + "otherList.add(this);\n");
+              sb.append(ind(6) + "resolvedElement.set" + getImplAttributeName() + "(otherList);\n");
+            sb.append(ind(5) + "}\n");
+            sb.append(ind(5) + "l.set(i, resolvedElement);\n");
+          sb.append(ind(4) + "}\n");
+        sb.append(ind(3) + "}\n");
+        sb.append(ind(3) + "set" + getImplAttributeName() + "(l);\n");
+      sb.append(ind(2) + "}\n");
+    }
+    sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n");
+    sb.append(ind(1) + "}\n");
 
     // Add
     sb.append(ind(1) + "public void " + toTypeDecl() + ".add");
@@ -404,7 +426,41 @@ aspect BackendBidirectionalAPI {
 
   public void RelationComponent.generateBiManyOne(StringBuilder sb) {
     // Get
-    generateGetMany(sb);
+    // getXs
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+    sb.append(".get" + nameCapitalized() + "s() {\n");
+    sb.append(ind(2) + "return get" + nameCapitalized() + "List();\n");
+    sb.append(ind(1) + "}\n");
+
+    // getXList
+    sb.append(ind(1) + "public java.util.List<" + ofTypeDecl() + "> " + toTypeDecl());
+    sb.append(".get" + nameCapitalized() + "List() {\n");
+    sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> l = get" + getImplAttributeName() + "();\n");
+    // resolve the entire list
+    if (resolverHelper) {
+      sb.append(ind(2) + "if (l != null) {\n");
+        sb.append(ind(3) + "for (int i = 0; i < l.size(); i++) {\n");
+          sb.append(ind(4) + ofTypeDecl() + " element = l.get(i);\n");
+          sb.append(ind(4) + "if (element.unresolved()) {\n");
+            sb.append(ind(5) + ofTypeDecl() + " resolvedElement = resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i);\n");
+            sb.append(ind(5) + toTypeDecl() + " oldTarget = resolvedElement.get" + getImplAttributeName() + "();\n");
+            sb.append(ind(5) + "if (oldTarget != null && oldTarget != this) {\n");
+              sb.append(ind(6) + "oldTarget.get" + getImplAttributeName() + "().remove(resolvedElement);\n");
+            sb.append(ind(5) + "}\n");
+            sb.append(ind(5) + "if (oldTarget == this) {\n");
+              sb.append(ind(6) + "l.remove(i);\n");
+              sb.append(ind(6) + "i--;\n");
+            sb.append(ind(5) + "} else {\n");
+              sb.append(ind(6) + "resolvedElement.set" + getImplAttributeName() + "(this);\n");
+              sb.append(ind(6) + "l.set(i, resolvedElement);\n");
+            sb.append(ind(5) + "}\n");
+          sb.append(ind(4) + "}\n");
+        sb.append(ind(3) + "}\n");
+        sb.append(ind(3) + "set" + getImplAttributeName() + "(l);\n");
+      sb.append(ind(2) + "}\n");
+    }
+    sb.append(ind(2) + "return l != null ? Collections.unmodifiableList(l) : Collections.emptyList();\n");
+    sb.append(ind(1) + "}\n");
 
     // Add
     sb.append(ind(1) + "public void " + toTypeDecl() + ".add");