diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd
index 3eac5c61a5590a69678725e4f3797c4c14b7058b..7b3de41ae6826342dc56642c5457235a46409078 100644
--- a/src/main/jastadd/Backend.jadd
+++ b/src/main/jastadd/Backend.jadd
@@ -229,6 +229,17 @@ aspect BackendDirectedAPI {
     sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n");
     sb.append(ind(1) + "}\n");
 
+    // Insert / add at specific position
+    sb.append(ind(1) + "public void " + toTypeDecl() + ".add" + nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n");
+    sb.append(ind(2) + "assertNotNull(o);\n");
+    sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n");
+    sb.append(ind(2) + "if (list == null) {\n");
+    sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n");
+    sb.append(ind(2) + "}\n");
+    sb.append(ind(2) + "list.add(index, o);\n");
+    sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n");
+    sb.append(ind(1) + "}\n");
+
     // Remove
     sb.append(ind(1) + "public void " + toTypeDecl() + ".remove");
     sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
@@ -416,6 +427,24 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(list2);\n");
     sb.append(ind(1) + "}\n");
 
+    // Insert / add at specific position
+    sb.append(ind(1) + "public void " + toTypeDecl() + ".add" + nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n");
+    sb.append(ind(2) + "assertNotNull(o);\n");
+    sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n");
+    sb.append(ind(2) + "if (list == null) {\n");
+    sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n");
+    sb.append(ind(2) + "}\n");
+    sb.append(ind(2) + ASTNode.listClass + "<" + otherSide().ofTypeDecl() + "> list2 = o.get"
+    + otherSide().getImplAttributeName() + "();\n");
+    sb.append(ind(2) + "if (list2 == null) {\n");
+    sb.append(ind(3) + "list2 = new "+ ASTNode.listClass + "<>();\n");
+    sb.append(ind(2) + "}\n");
+    sb.append(ind(2) + "list.add(index, o);\n");
+    sb.append(ind(2) + "list2.add(this);\n");
+    sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n");
+    sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(list2);\n");
+    sb.append(ind(1) + "}\n");
+
     // Remove
     sb.append(ind(1) + "public void " + toTypeDecl() + ".remove");
     sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
@@ -494,6 +523,23 @@ aspect BackendBidirectionalAPI {
     sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(this);\n");
     sb.append(ind(1) + "}\n");
 
+    // Insert / add at specific position
+    sb.append(ind(1) + "public void " + toTypeDecl() + ".add" + nameCapitalized() + "(int index, " + ofTypeDecl() + " o) {\n");
+      sb.append(ind(2) + "assertNotNull(o);\n");
+      sb.append(ind(2) + "if (o != null && o.get" + otherSide().getImplAttributeName() + "() != null) {\n");
+        sb.append(ind(3) + ASTNode.listClass + "<" + ofTypeDecl() + "> list2 = o.get" + otherSide().getImplAttributeName() + "().get" + getImplAttributeName() + "();\n");
+        sb.append(ind(3) + "if (list2.remove(o))\n");
+          sb.append(ind(4) + "o.get" + otherSide().getImplAttributeName() + "().set" + getImplAttributeName() + "(list2);\n");
+      sb.append(ind(2) + "}\n");
+      sb.append(ind(2) + ASTNode.listClass + "<" + ofTypeDecl() + "> list = get" + getImplAttributeName() + "();\n");
+      sb.append(ind(2) + "if (list == null) {\n");
+        sb.append(ind(3) + "list = new " + ASTNode.listClass + "<>();\n");
+      sb.append(ind(2) + "}\n");
+      sb.append(ind(2) + "list.add(index, o);\n");
+      sb.append(ind(2) + "set" + getImplAttributeName() + "(list);\n");
+      sb.append(ind(2) + "o.set" + otherSide().getImplAttributeName() + "(this);\n");
+    sb.append(ind(1) + "}\n");
+
     // Remove
     sb.append(ind(1) + "public void " + toTypeDecl() + ".remove");
     sb.append(nameCapitalized() + "(" + ofTypeDecl() + " o) {\n");
diff --git a/src/test/java/org/jastadd/relast/tests/InsertRelations.java b/src/test/java/org/jastadd/relast/tests/InsertRelations.java
new file mode 100644
index 0000000000000000000000000000000000000000..c10d9188041f98f4a27aa7ea49f5ba906e62e14a
--- /dev/null
+++ b/src/test/java/org/jastadd/relast/tests/InsertRelations.java
@@ -0,0 +1,219 @@
+package org.jastadd.relast.tests;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import relations.ast.A;
+import relations.ast.B;
+import relations.ast.Root;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import static org.jastadd.relast.tests.TestHelpers.readFile;
+import static org.junit.jupiter.api.Assertions.*;
+
+
+@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
+class InsertRelations {
+  private Root r;
+  private A a1;
+  private A a2;
+  private A a3;
+  private B b1;
+  private B b2;
+  private B b3;
+
+  /**
+   * rel A.Bi7* <-> B.Bi7;
+   */
+  @Test
+  void testBi7() {
+    setup();
+    a2.addBi7(0, b2);
+
+    assertEquals(a1.getBi7s(), Arrays.asList());
+    assertEquals(a1.getBi7List(), Arrays.asList());
+    assertEquals(a2.getBi7s(), Arrays.asList(b2));
+    assertEquals(a2.getBi7List(), Arrays.asList(b2));
+    assertNull(b1.getBi7());
+    assertSame(b2.getBi7(), a2);
+    assertNull(b3.getBi7());
+
+    a2.addBi7(0, b3);
+    a1.addBi7(0, b2);
+
+    assertEquals(a1.getBi7s(), Arrays.asList(b2));
+    assertEquals(a1.getBi7List(), Arrays.asList(b2));
+    assertEquals(a2.getBi7s(), Arrays.asList(b3));
+    assertEquals(a2.getBi7List(), Arrays.asList(b3));
+    assertNull(b1.getBi7());
+    assertSame(b2.getBi7(), a1);
+    assertSame(b3.getBi7(), a2);
+
+    a1.addBi7(b1);
+
+    assertEquals(a1.getBi7s(), Arrays.asList(b2, b1));
+    assertEquals(a1.getBi7List(), Arrays.asList(b2, b1));
+    assertEquals(a2.getBi7s(), Arrays.asList(b3));
+    assertEquals(a2.getBi7List(), Arrays.asList(b3));
+    assertSame(b1.getBi7(), a1);
+    assertSame(b2.getBi7(), a1);
+    assertSame(b3.getBi7(), a2);
+
+    a1.addBi7(b1);
+
+    assertEquals(a1.getBi7s(), Arrays.asList(b2, b1));
+    assertEquals(a1.getBi7List(), Arrays.asList(b2, b1));
+    assertEquals(a2.getBi7s(), Arrays.asList(b3));
+    assertEquals(a2.getBi7List(), Arrays.asList(b3));
+    assertSame(b1.getBi7(), a1);
+    assertSame(b2.getBi7(), a1);
+    assertSame(b3.getBi7(), a2);
+
+    a1.removeBi7(b1);
+
+    assertEquals(a1.getBi7s(), Arrays.asList(b2));
+    assertEquals(a1.getBi7List(), Arrays.asList(b2));
+    assertEquals(a2.getBi7s(), Arrays.asList(b3));
+    assertEquals(a2.getBi7List(), Arrays.asList(b3));
+    assertNull(b1.getBi7());
+    assertSame(b2.getBi7(), a1);
+    assertSame(b3.getBi7(), a2);
+  }
+
+
+  /**
+   * rel A.Bi8* <-> B.Bi8?;
+   */
+  @Test
+  void testBi8() {
+    setup();
+    a2.addBi8(0, b2);
+
+    assertEquals(a1.getBi8s(), Arrays.asList());
+    assertEquals(a1.getBi8List(), Arrays.asList());
+    assertEquals(a2.getBi8s(), Arrays.asList(b2));
+    assertEquals(a2.getBi8List(), Arrays.asList(b2));
+    assertNull(b1.getBi8());
+    assertSame(b2.getBi8(), a2);
+    assertNull(b3.getBi8());
+
+    a2.addBi8(0, b3);
+    a1.addBi8(0, b2);
+
+    assertEquals(a1.getBi8s(), Arrays.asList(b2));
+    assertEquals(a1.getBi8List(), Arrays.asList(b2));
+    assertEquals(a2.getBi8s(), Arrays.asList(b3));
+    assertEquals(a2.getBi8List(), Arrays.asList(b3));
+    assertNull(b1.getBi8());
+    assertSame(b2.getBi8(), a1);
+    assertSame(b3.getBi8(), a2);
+
+    a1.addBi8(0, b1);
+
+    assertEquals(a1.getBi8s(), Arrays.asList(b1, b2));
+    assertEquals(a1.getBi8List(), Arrays.asList(b1, b2));
+    assertEquals(a2.getBi8s(), Arrays.asList(b3));
+    assertEquals(a2.getBi8List(), Arrays.asList(b3));
+    assertSame(b1.getBi8(), a1);
+    assertSame(b2.getBi8(), a1);
+    assertSame(b3.getBi8(), a2);
+
+    a1.addBi8(0, b1);
+
+    assertEquals(a1.getBi8s(), Arrays.asList(b1, b2));
+    assertEquals(a1.getBi8List(), Arrays.asList(b1, b2));
+    assertEquals(a2.getBi8s(), Arrays.asList(b3));
+    assertEquals(a2.getBi8List(), Arrays.asList(b3));
+    assertSame(b1.getBi8(), a1);
+    assertSame(b2.getBi8(), a1);
+    assertSame(b3.getBi8(), a2);
+
+    a1.removeBi8(b1);
+
+    assertEquals(a1.getBi8s(), Arrays.asList(b2));
+    assertEquals(a1.getBi8List(), Arrays.asList(b2));
+    assertEquals(a2.getBi8s(), Arrays.asList(b3));
+    assertEquals(a2.getBi8List(), Arrays.asList(b3));
+    assertNull(b1.getBi8());
+    assertSame(b2.getBi8(), a1);
+    assertSame(b3.getBi8(), a2);
+  }
+
+
+  /**
+   * rel A.Bi9* <-> B.Bi9*;
+   */
+  @Test
+  void testBi9() {
+    setup();
+    a1.addBi9(0, b1);
+    a1.addBi9(0, b2);
+
+    assertEquals(a1.getBi9s(), Arrays.asList(b2, b1));
+    assertEquals(a1.getBi9List(), Arrays.asList(b2, b1));
+    assertEquals(a2.getBi9s(), Arrays.asList());
+    assertEquals(a2.getBi9List(), Arrays.asList());
+    assertEquals(a3.getBi9s(), Arrays.asList());
+    assertEquals(a3.getBi9List(), Arrays.asList());
+    assertEquals(b1.getBi9s(), Arrays.asList(a1));
+    assertEquals(b1.getBi9List(), Arrays.asList(a1));
+    assertEquals(b2.getBi9s(), Arrays.asList(a1));
+    assertEquals(b2.getBi9List(), Arrays.asList(a1));
+    assertEquals(b3.getBi9s(), Arrays.asList());
+    assertEquals(b3.getBi9List(), Arrays.asList());
+
+    b3.addBi9(0, a1);
+    b3.addBi9(0, a3);
+    b3.addBi9(0, a1);
+
+    assertEquals(a1.getBi9s(), Arrays.asList(b2, b1, b3, b3));
+    assertEquals(a1.getBi9List(), Arrays.asList(b2, b1, b3, b3));
+    assertEquals(a2.getBi9s(), Arrays.asList());
+    assertEquals(a2.getBi9List(), Arrays.asList());
+    assertEquals(a3.getBi9s(), Arrays.asList(b3));
+    assertEquals(a3.getBi9List(), Arrays.asList(b3));
+    assertEquals(b1.getBi9s(), Arrays.asList(a1));
+    assertEquals(b1.getBi9List(), Arrays.asList(a1));
+    assertEquals(b2.getBi9s(), Arrays.asList(a1));
+    assertEquals(b2.getBi9List(), Arrays.asList(a1));
+    assertEquals(b3.getBi9s(), Arrays.asList(a1, a3, a1));
+    assertEquals(b3.getBi9List(), Arrays.asList(a1, a3, a1));
+
+    b3.removeBi9(a1);
+
+    assertEquals(a1.getBi9s(), Arrays.asList(b2, b1, b3));
+    assertEquals(a1.getBi9List(), Arrays.asList(b2, b1, b3));
+    assertEquals(a2.getBi9s(), Arrays.asList());
+    assertEquals(a2.getBi9List(), Arrays.asList());
+    assertEquals(a3.getBi9s(), Arrays.asList(b3));
+    assertEquals(a3.getBi9List(), Arrays.asList(b3));
+    assertEquals(b1.getBi9s(), Arrays.asList(a1));
+    assertEquals(b1.getBi9List(), Arrays.asList(a1));
+    assertEquals(b2.getBi9s(), Arrays.asList(a1));
+    assertEquals(b2.getBi9List(), Arrays.asList(a1));
+    assertEquals(b3.getBi9s(), Arrays.asList(a3, a1));
+    assertEquals(b3.getBi9List(), Arrays.asList(a3, a1));
+  }
+
+
+  @BeforeEach
+  void setup() {
+    r = new Root();
+    a1 = new A("a1");
+    a2 = new A("a2");
+    a3 = new A("a3");
+    b1 = new B("b1");
+    b2 = new B("b2");
+    b3 = new B("b3");
+
+    r.addA(a1);
+    r.addA(a2);
+    r.addA(a3);
+    r.addB(b1);
+    r.addB(b2);
+    r.addB(b3);
+  }
+}