diff --git a/Examples/TextBind/index.html b/Examples/TextBind/index.html
index e97b932e4f9baf030331939450dd45514e093c76..9bfd45256bac5e110bcfc2ea42ee2a0326b60cf4 100644
--- a/Examples/TextBind/index.html
+++ b/Examples/TextBind/index.html
@@ -1,20 +1,12 @@
 <!DOCTYPE html>
 <html>
-<head>
-  <meta charset=utf-8 />
-  <title>Y Example</title>
+<body>
+  <button id="button">Disconnect</button>
+  <h1 id="contenteditable" contentEditable></h1>
+  <textarea style="width:80%;" rows=40 id="textfield"></textarea>
+
   <script src="../../node_modules/simplewebrtc/simplewebrtc.bundle.js"></script>
   <script src="../../y.js"></script>
   <script src="./index.js"></script>
-</head>
-<body>
-<h1 id="contenteditable" contentEditable> yjs Tutorial</h1>
-<p> Collaborative Json editing with <a href="https://github.com/rwth-acis/yjs/">yjs</a>
-and XMPP Connector. </p>
-
-<textarea style="width:80%;" rows=40 id="textfield"></textarea>
-
-<p> <a href="https://github.com/y-js/yjs/">yjs</a> is a Framework for Real-Time collaboration on arbitrary data types.
-</p>
 </body>
 </html>
diff --git a/Examples/TextBind/index.js b/Examples/TextBind/index.js
index 90d5657f0488c867c2c80a1fba5abd74e28e86d6..d489a02ac95afd3793eb02d83c3e48947388bd25 100644
--- a/Examples/TextBind/index.js
+++ b/Examples/TextBind/index.js
@@ -1,25 +1,47 @@
 /* global Y */
 
+// create a shared object. This function call will return a promise!
 Y({
   db: {
     name: 'Memory'
   },
   connector: {
     name: 'WebRTC',
-    room: 'mineeeeeee',
+    room: 'TextBindDemo',
     debug: true
   }
 }).then(function (yconfig) {
-  window.y = yconfig.root
+  // yconfig holds all the information about the shared object
   window.yconfig = yconfig
+  // yconfig.root holds the shared element
+  window.y = yconfig.root
+
+  // now we bind the textarea and the contenteditable h1 element
+  // to a shared element
   var textarea = document.getElementById('textfield')
   var contenteditable = document.getElementById('contenteditable')
   yconfig.root.observePath(['text'], function (text) {
+    // every time the 'text' property of the yconfig.root changes,
+    // this function is called. Then we bind it to the html elements
     if (text != null) {
+      // when the text property is deleted, text may be undefined!
+      // This is why we have to check if text exists..
       text.bind(textarea)
       text.bind(contenteditable)
-      window.ytext = text
     }
   })
+  // create a shared TextBind
   yconfig.root.set('text', Y.TextBind)
+
+  // We also provide a button for disconnecting/reconnecting the shared element
+  var button = document.querySelector('#button')
+  button.onclick = function () {
+    if (button.innerText === 'Disconnect') {
+      yconfig.disconnect()
+      button.innerText = 'Reconnect'
+    } else {
+      yconfig.reconnect()
+      button.innerText = 'Disconnect'
+    }
+  }
 })
diff --git a/gulpfile.js b/gulpfile.js
index 5f94732975045a2a27941b934d229ce24cb786c0..26a03eb4190d66f6f0d3e3458ebe0bc4032b9a9a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -97,7 +97,7 @@ if (options.regenerator) {
   files.test = polyfills.concat(files.test)
 }
 
-gulp.task('build:deploy', function () {
+gulp.task('deploy', function () {
   gulp.src(files.src)
     .pipe(sourcemaps.init())
     .pipe(concat('y.js'))
@@ -120,6 +120,13 @@ gulp.task('build:test', function () {
   if (!options.regenerator) {
     babelOptions.blacklist = 'regenerator'
   }
+  gulp.src(files.src)
+    .pipe(sourcemaps.init())
+    .pipe(concat('y.js'))
+    .pipe(babel(babelOptions))
+    .pipe(sourcemaps.write())
+    .pipe(gulp.dest('.'))
+
   return gulp.src('src/**/*.js')
     .pipe(sourcemaps.init())
     .pipe(babel(babelOptions))
@@ -140,10 +147,6 @@ gulp.task('dev:browser', ['build:test'], function () {
     .pipe(jasmineBrowser.server({port: options.testport}))
 })
 
-gulp.task('dev:deploy', ['build:deploy'], function () {
-  gulp.watch('src/**/*.js', ['build:deploy'])
-})
-
 gulp.task('dev', ['build:test'], function () {
   gulp.start('dev:browser')
   gulp.start('dev:node')
diff --git a/src/Connectors/WebRTC.js b/src/Connectors/WebRTC.js
index 954aa0d0ebb87ed1f440e6a9f02a57ae00e4fe33..91e5ca26f7d76820b60ecae789bfaed9af9d604d 100644
--- a/src/Connectors/WebRTC.js
+++ b/src/Connectors/WebRTC.js
@@ -1,4 +1,4 @@
-/* global Y */
+/* global Y, SimpleWebRTC */
 'use strict'
 
 class WebRTC extends Y.AbstractConnector {
@@ -11,21 +11,16 @@ class WebRTC extends Y.AbstractConnector {
     }
     options.role = 'slave'
     super(y, options)
-
-    var room = options.room
-
-    var webrtcOptions = {
+    this.webrtcOptions = {
       url: options.url || 'https://yatta.ninja:8888',
       room: options.room
     }
-
-    var swr = new SimpleWebRTC(webrtcOptions) // eslint-disable-line no-undef
+    var swr = new SimpleWebRTC(this.webrtcOptions)
     this.swr = swr
     var self = this
-
     swr.once('connectionReady', function (userId) {
       // SimpleWebRTC (swr) is initialized
-      swr.joinRoom(room)
+      swr.joinRoom(self.webrtcOptions.room)
 
       swr.once('joinedRoom', function () {
         self.setUserId(userId)
@@ -61,6 +56,14 @@ class WebRTC extends Y.AbstractConnector {
       })
     })
   }
+  disconnect () {
+    this.swr.leaveRoom()
+    super.disconnect()
+  }
+  reconnect () {
+    this.swr.joinRoom(this.webrtcOptions.room)
+    super.reconnect()
+  }
   send (uid, message) {
     var self = this
     // we have to make sure that the message is sent under all circumstances
diff --git a/src/OperationStore.js b/src/OperationStore.js
index 1127b9342290a329225c29299e4261bc8a9fcd84..954d9234ca90a1b2309e6e04921d7e250aecd6b1 100644
--- a/src/OperationStore.js
+++ b/src/OperationStore.js
@@ -115,10 +115,26 @@ class AbstractTransaction {
       })
     }
   }
+
+  * deleteList (start) {
+    if (this.store.y.connector.isSynced) {
+      while (start != null && this.store.y.connector.isSynced) {
+        start = (yield* this.getOperation(start))
+        start.gc = true
+        yield* this.setOperation(start)
+        // TODO: will always reset the parent..
+        this.store.gc1.push(start.id)
+        start = start.right
+      }
+    } else {
+      // TODO: when not possible??? do later in (gcWhenSynced)
+    }
+  }
+
   /*
     Mark an operation as deleted, and add it to the GC, if possible.
   */
-  * deleteOperation (targetId) {
+  * deleteOperation (targetId, preventCallType) {
     var target = yield* this.getOperation(targetId)
 
     if (target == null || !target.deleted) {
@@ -129,12 +145,31 @@ class AbstractTransaction {
       if (!target.deleted) {
         // set deleted & notify type
         target.deleted = true
-        var type = this.store.initializedTypes[JSON.stringify(target.parent)]
-        if (type != null) {
-          yield* type._changed(this, {
-            struct: 'Delete',
-            target: targetId
-          })
+        if (!preventCallType) {
+          var type = this.store.initializedTypes[JSON.stringify(target.parent)]
+          if (type != null) {
+            yield* type._changed(this, {
+              struct: 'Delete',
+              target: targetId
+            })
+          }
+        }
+        // delete containing lists
+        if (target.start != null) {
+          // TODO: don't do it like this .. -.-
+          yield* this.deleteList(target.start)
+          yield* this.deleteList(target.id)
+        }
+        if (target.map != null) {
+          for (var name in target.map) {
+            yield* this.deleteList(target.map[name])
+          }
+          // TODO: here to..  (see above)
+          yield* this.deleteList(target.id)
+        }
+        if (target.opContent != null) {
+          yield* this.deleteOperation(target.opContent)
+          target.opContent = null
         }
       }
       var left = target.left != null ? yield* this.getOperation(target.left) : null
@@ -182,10 +217,12 @@ class AbstractTransaction {
     // if op exists, then clean that mess up..
     var o = yield* this.getOperation(id)
     if (o != null) {
+      /*
       if (!o.deleted) {
         yield* this.deleteOperation(id)
         o = yield* this.getOperation(id)
       }
+      */
 
       // remove gc'd op from the left op, if it exists
       if (o.left != null) {
@@ -233,23 +270,26 @@ class AbstractTransaction {
         yield* this.setOperation(right)
       }
 
-      // remove gc'd op from parent, if it exists
-      var parent = yield* this.getOperation(o.parent)
-      var setParent = false // whether to save parent to the os
-      if (Y.utils.compareIds(parent.start, o.id)) {
-        // gc'd op is the start
-        setParent = true
-        parent.start = o.right
-      }
-      if (Y.utils.compareIds(parent.end, o.id)) {
-        // gc'd op is the end
-        setParent = true
-        parent.end = o.left
-      }
-      if (setParent) {
-        yield* this.setOperation(parent)
+      if (o.parent != null) {
+        // remove gc'd op from parent, if it exists
+        var parent = yield* this.getOperation(o.parent)
+        var setParent = false // whether to save parent to the os
+        if (Y.utils.compareIds(parent.start, o.id)) {
+          // gc'd op is the start
+          setParent = true
+          parent.start = o.right
+        }
+        if (Y.utils.compareIds(parent.end, o.id)) {
+          // gc'd op is the end
+          setParent = true
+          parent.end = o.left
+        }
+        if (setParent) {
+          yield* this.setOperation(parent)
+        }
       }
-      yield* this.removeOperation(o.id) // actually remove it from the os
+      // finally remove it from the os
+      yield* this.removeOperation(o.id)
     }
   }
 }
diff --git a/src/OperationStores/Memory.js b/src/OperationStores/Memory.js
index 743c59d4967da48f679afdf00943190aa1cb8a8f..a660a3132f9027b1d1458cf21888565f25a4d042 100644
--- a/src/OperationStores/Memory.js
+++ b/src/OperationStores/Memory.js
@@ -203,12 +203,11 @@ Y.Memory = (function () {
       for (var i in deletions) {
         var del = deletions[i]
         var id = [del[0], del[1]]
+        // always try to delete..
+        yield* this.deleteOperation(id)
         if (del[2]) {
           // gc
           yield* this.garbageCollectOperation(id)
-        } else {
-          // delete
-          yield* this.deleteOperation(id)
         }
       }
     }
diff --git a/src/Struct.js b/src/Struct.js
index 704a48a5b6b5600e319071f44d1421e3ddccb288..03910719baeef57f1c04f1db3861b208491400cf 100644
--- a/src/Struct.js
+++ b/src/Struct.js
@@ -194,12 +194,20 @@ var Struct = {
         yield* this.setOperation(right)
       }
 
-      // notify parent
+      // update parents .map/start/end properties
       if (op.parentSub != null) {
         if (left == null) {
           parent.map[op.parentSub] = op.id
           yield* this.setOperation(parent)
         }
+        // is a child of a map struct.
+        // Then also make sure that only the most left element is not deleted
+        if (op.right != null) {
+          yield* this.deleteOperation(op.right, true)
+        }
+        if (op.left != null) {
+          yield* this.deleteOperation(op.id, true)
+        }
       } else {
         if (right == null || left == null) {
           if (right == null) {