diff --git a/src/SpecHelper.js b/src/SpecHelper.js
index 4097b7a7b9ca425d37f664e9d75c677952215e73..28abcf5bc385cc7e59e277679d546f51e52f174a 100644
--- a/src/SpecHelper.js
+++ b/src/SpecHelper.js
@@ -208,6 +208,7 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
         yield* this.os.iterate(this, null, null, function * (o) {
           o = Y.utils.copyObject(o)
           delete o.origin
+          delete o.originOf
           db1.push(o)
         })
       })
@@ -222,6 +223,7 @@ g.compareAllUsers = async(function * compareAllUsers (users) {
         yield* this.os.iterate(this, null, null, function * (o) {
           o = Y.utils.copyObject(o)
           delete o.origin
+          delete o.originOf
           expect(db1[count++]).toEqual(o)
         })
       })
diff --git a/src/Struct.js b/src/Struct.js
index 0ea0dd132a593c530ad6074b2f4120e0ebca1ac2..6638127817a24e68339dd736a706aa4ab2c0be33 100644
--- a/src/Struct.js
+++ b/src/Struct.js
@@ -126,6 +126,19 @@ module.exports = function (Y/* :any */) {
       execute: function *(op) {
         var i // loop counter
         var distanceToOrigin = i = yield* Struct.Insert.getDistanceToOrigin.call(this, op) // most cases: 0 (starts from 0)
+
+        if (op.origin != null) {
+          // we save in origin that op originates in it
+          // we need that later when we eventually garbage collect origin (see transaction)
+          var origin = yield* this.getOperation(op.origin)
+          if (origin.originOf == null) {
+            origin.originOf = []
+          }
+          origin.originOf.push(op.id)
+          yield* this.setOperation(origin)
+        }
+
+        // now we begin to insert op in the list of insertions..
         var o
         var parent
         var start
diff --git a/src/Transaction.js b/src/Transaction.js
index 45d2e8d6342ce90f6d65ce3f622eb115cf08d5c5..c1e1db14d7e8e66902fd99551b58c4795c76c96e 100644
--- a/src/Transaction.js
+++ b/src/Transaction.js
@@ -362,23 +362,31 @@ module.exports = function (Y/* :any */) {
         if (o.right != null) {
           var right = yield* this.getOperation(o.right)
           right.left = o.left
-          if (Y.utils.compareIds(right.origin, o.id)) { // rights origin is o
+
+          if (Y.utils.compareIds(right.origin, id)) { // rights origin is o
             // find new origin of right ops
             // origin is the first left deleted operation
             var neworigin = o.left
+            var neworigin_ = null
             while (neworigin != null) {
-              var neworigin_ = yield* this.getOperation(neworigin)
+              neworigin_ = yield* this.getOperation(neworigin)
               if (neworigin_.deleted) {
                 break
               }
               neworigin = neworigin_.left
             }
 
+            // reset origin of all right ops (except first right - duh!),
+
+            /* ** The following code does not rely on the the originOf property **
+                  I recently added originOf to all Insert Operations (see Struct.Insert.execute),
+                  which saves which operations originate in a Insert operation.
+                  Garbage collecting without originOf is more memory efficient, but is nearly impossible for large texts, or lists!
+                  But I keep this code for now
+            ```
             // reset origin of right
             right.origin = neworigin
-
-            // reset origin of all right ops (except first right - duh!),
-            // until you find origin pointer to the left of o
+            // search until you find origin pointer to the left of o
             if (right.right != null) {
               var i = yield* this.getOperation(right.right)
               var ids = [o.id, o.right]
@@ -399,9 +407,41 @@ module.exports = function (Y/* :any */) {
                 }
               }
             }
-          } /* otherwise, rights origin is to the left of o,
-               then there is no right op (from o), that origins in o */
-          yield* this.setOperation(right)
+            ```
+            */
+            // ** Now the new implementation starts **
+            // reset neworigin of all originOf[*]
+            for (var _i in o.originOf) {
+              var originsIn = yield* this.getOperation(o.originOf[_i])
+              if (originsIn != null) {
+                originsIn.origin = neworigin
+                yield* this.setOperation(originsIn)
+              }
+            }
+            if (neworigin != null) {
+              if (neworigin_.originOf == null) {
+                neworigin_.originOf = o.originOf
+              } else {
+                neworigin_.originOf = o.originOf.concat(neworigin_.originOf)
+              }
+              yield* this.setOperation(neworigin_)
+            }
+            // we don't need to set right here, because
+            // right should be in o.originOf => it is set it the previous for loop
+          } else {
+            // we didn't need to reset the origin of right
+            // so we have to set right here
+            yield* this.setOperation(right)
+          }
+          // o may originate in another operation.
+          // Since o is deleted, we have to reset o.origin's `originOf` property
+          if (o.origin != null) {
+            var origin = yield* this.getOperation(o.origin)
+            origin.originOf = origin.originOf.filter(function (_id) {
+              return !Y.utils.compareIds(id, _id)
+            })
+            yield* this.setOperation(origin)
+          }
         }
 
         if (o.parent != null) {