diff --git a/declarations/Structs.js b/declarations/Structs.js
index 7044e20d4d4b94cd1a651294e22e74064ea213dc..e65c7207c4d4a676968610ae36ed40e8e00519a1 100644
--- a/declarations/Structs.js
+++ b/declarations/Structs.js
@@ -1,7 +1,7 @@
 /* @flow */
 
 type UserId = string
-type Id = [UserId, number]
+type Id = [UserId, number|string]
 
 /*
 type Struct = {
@@ -11,6 +11,7 @@ type Struct = {
   target?: Id,
   struct: 'Insert' | 'Delete'
 }*/
+
 type Struct = Insertion | Deletion
 type Operation = Struct
 
@@ -31,6 +32,19 @@ type Deletion = {
   struct: 'Delete'
 }
 
+type MapStruct = {
+  id: Id,
+  type: TypeNames,
+  map: any
+}
+
+type ListStruct = {
+  id: Id,
+  type: TypeNames,
+  start: Id,
+  end: Id
+}
+
 
 type MessageSyncStep1 = {
   type: 'sync step 1',
diff --git a/declarations/Y.js b/declarations/Y.js
index 6c730a76b14ec59bfe4a1692c6cab5826161af05..9a91a83df857ea8a916bada9ccd53981f6d9cb3c 100644
--- a/declarations/Y.js
+++ b/declarations/Y.js
@@ -14,6 +14,8 @@ type YConfig = {
 	root: Object
 }
 
+type TypeName = 'array' | 'map' | 'text'
+
 declare var YConcurrency_TestingMode : boolean
 
 type Transaction<A> = Generator<any, A, any>
diff --git a/dist b/dist
index b471c91d1d70b1d9e31ba81664d8fab4aff414a2..434432a742088e4f53aee0230353c18b5e621211 160000
--- a/dist
+++ b/dist
@@ -1 +1 @@
-Subproject commit b471c91d1d70b1d9e31ba81664d8fab4aff414a2
+Subproject commit 434432a742088e4f53aee0230353c18b5e621211
diff --git a/gulpfile.helper.js b/gulpfile.helper.js
index aafa6980f4a40916766a19035be3c16c26fcfbf2..f4f152435570dce5b50fef360388d6fbaa93718d 100644
--- a/gulpfile.helper.js
+++ b/gulpfile.helper.js
@@ -31,7 +31,9 @@ module.exports = function (gulp, helperOptions) {
   }
 
   if (options.includeRuntime) {
-    files.dist = ['node_modules/regenerator/runtime.js', files.dist]
+    files.distEs5 = ['node_modules/regenerator/runtime.js', files.dist]
+  } else {
+    files.distEs5 = [files.dist]
   }
 
   gulp.task('dist:es5', function () {
@@ -39,14 +41,14 @@ module.exports = function (gulp, helperOptions) {
       presets: ['es2015']
     }
     return (browserify({
-      entries: files.dist,
+      entries: files.distEs5,
       debug: true
     }).transform('babelify', babelOptions)
       .bundle()
       .pipe(source(options.targetName))
       .pipe(buffer())
       .pipe($.sourcemaps.init({loadMaps: true}))
-      .pipe($.uglify())
+      .pipe($.if(!options.debug, $.uglify()))
       .pipe($.sourcemaps.write('.'))
       .pipe(gulp.dest('./dist/')))
   })
diff --git a/gulpfile.js b/gulpfile.js
index da21661dd0b8129964fb4dab4a8fd8177b8342f4..7ea185a7e95e75e547cefbe8aa9c0907942eb54b 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -59,9 +59,9 @@ require('./gulpfile.helper.js')(gulp, {
   ]
 })
 
-gulp.task('dev:examples', ['updateSubmodule', 'watch:dist'], function () {
+gulp.task('dev:examples', ['watch:dist'], function () {
   // watch all distfiles and copy them to bower_components
-  var distfiles = ['./dist/*.js', './dist/*.js.map', '../y-*/dist/*.js', '../y-*/dist/*.js.map']
+  var distfiles = ['./dist/*.{js,es6}', './dist/*.{js,es6}.map', '../y-*/dist/*.{js,es6}', '../y-*/dist/*.{js,es6}.map']
   gulp.src(distfiles)
     .pipe($.watch(distfiles))
     .pipe($.rename(function (path) {
diff --git a/src/Database.js b/src/Database.js
index c1441769c9b47f6e5dd05fb9f7dd72cba4d31619..57aa388424897a6b6d6772e66984dcda8c815f7e 100644
--- a/src/Database.js
+++ b/src/Database.js
@@ -186,8 +186,8 @@ module.exports = function (Y /* :any */) {
       }
     }
     getNextOpId () {
-      if (this._temporaryUserIdGenerator != null) {
-        return this._temporaryUserIdGenerator()
+      if (this._nextUserId != null) {
+        return this._nextUserId
       } else if (this.userId == null) {
         throw new Error('OperationStore not yet initialized!')
       } else {
@@ -390,7 +390,7 @@ module.exports = function (Y /* :any */) {
       }
     }
     requestTransaction (makeGen/* :any */, callImmediately) {
-      if (callImmediately) {
+      if (true || callImmediately) { // TODO: decide whether this is ok or not..
         this.waitingTransactions.push(makeGen)
         if (!this.transactionInProgress) {
           this.transactionInProgress = true
diff --git a/src/SpecHelper.js b/src/SpecHelper.js
index da92a2c35c7fe9f52425f0af8b5bace13d286491..a1c70a0c1ec5c69aa5756f96b18942269c07aa42 100644
--- a/src/SpecHelper.js
+++ b/src/SpecHelper.js
@@ -85,7 +85,7 @@ function * applyTransactions (relAmount, numberOfTransactions, objects, users, t
     var r = Math.random()
     if (r >= 0.5) {
       // 50% chance to flush
-      Y.utils.globalRoom.flushOne() // flushes for some user.. (not necessarily 0)
+      yield Y.utils.globalRoom.flushOne() // flushes for some user.. (not necessarily 0)
     } else if (r >= 0.05) {
       // 45% chance to create operation
       randomTransaction(getRandom(objects))
@@ -245,6 +245,9 @@ g.createUsers = async(function * createUsers (self, numberOfUsers, database) {
       connector: {
         name: 'Test',
         debug: false
+      },
+      share: {
+        root: 'Map'
       }
     }))
   }
diff --git a/src/Transaction.js b/src/Transaction.js
index fdec10749c76dde41f1ebf58de0a381b4bef2cbc..e78339b048f01c06940667d41413ff25ca08039f 100644
--- a/src/Transaction.js
+++ b/src/Transaction.js
@@ -91,7 +91,7 @@ module.exports = function (Y/* :any */) {
       var sid = JSON.stringify(id)
       var t = this.store.initializedTypes[sid]
       if (t == null) {
-        var op = yield* this.getOperation(id)
+        var op/* :MapStruct | ListStruct */ = yield* this.getOperation(id)
         if (op != null) {
           t = yield* Y[op.type].initType.call(this, this.store, op)
           this.store.initializedTypes[sid] = t
@@ -398,7 +398,7 @@ module.exports = function (Y/* :any */) {
 
         if (o.parent != null) {
           // remove gc'd op from parent, if it exists
-          var parent = yield* this.getOperation(o.parent)
+          var parent /* MapOperation */ = yield* this.getOperation(o.parent)
           var setParent = false // whether to save parent to the os
           if (o.parentSub != null) {
             if (Y.utils.compareIds(parent.map[o.parentSub], o.id)) {
@@ -558,8 +558,23 @@ module.exports = function (Y/* :any */) {
         })
       }
     }
-    * getOperation (id) {
-      return yield* this.os.find(id)
+    * getOperation (id/* :any */)/* :Transaction<any> */ {
+      var o = yield* this.os.find(id)
+      if (o != null || id[0] != '_') {
+        return o
+      } else {
+        // need to generate this operation
+        if (this.store._nextUserId == null) {
+          var typename= id[1].split('_')[0]
+          this.store._nextUserId = id
+          yield* Y[typename].createType.call(this)
+          delete this.store._nextUserId
+          return yield* this.os.find(id)
+        } else {
+          // Can only generate one operation at a time
+          return null
+        }
+      }
     }
     * removeOperation (id) {
       yield* this.os.delete(id)
diff --git a/src/Types/Map.spec.js b/src/Types/Map.spec.js
index e07d50adba1035df3ff1f1d96f27cf39da40d75b..4a8b73f096aa54108fa6b07149d6f5f5befb2d14 100644
--- a/src/Types/Map.spec.js
+++ b/src/Types/Map.spec.js
@@ -3,7 +3,7 @@
 'use strict'
 
 var Y = require('../SpecHelper.js')
-var numberOfYMapTests = 500
+var numberOfYMapTests = 50
 var repeatMapTeasts = 1
 
 for (let database of databases) {
@@ -12,10 +12,10 @@ for (let database of databases) {
 
     beforeEach(async(function * (done) {
       yield createUsers(this, 5, database)
-      y1 = this.users[0].root
-      y2 = this.users[1].root
-      y3 = this.users[2].root
-      y4 = this.users[3].root
+      y1 = this.users[0].share.root
+      y2 = this.users[1].share.root
+      y3 = this.users[2].share.root
+      y4 = this.users[3].share.root
       flushAll = Y.utils.globalRoom.flushAll
       done()
     }))
@@ -30,7 +30,7 @@ for (let database of databases) {
         expect(y1.get('stuff')).toEqual('stuffy')
         yield flushAll()
         for (var key in this.users) {
-          var u = this.users[key].root
+          var u = this.users[key].share.root
           expect(u.get('stuff')).toEqual('stuffy')
         }
         done()
@@ -56,7 +56,7 @@ for (let database of databases) {
 
         yield flushAll()
         for (var key in this.users) {
-          var r = this.users[key].root
+          var r = this.users[key].share.root
           expect(r.get('stuff')).toEqual('stuffy')
         }
         done()
@@ -69,7 +69,7 @@ for (let database of databases) {
         yield flushAll()
         for (var key in this.users) {
           var u = this.users[key]
-          expect(u.root.get('stuff')).toEqual('c0')
+          expect(u.share.root.get('stuff')).toEqual('c0')
         }
         done()
       }))
@@ -82,7 +82,7 @@ for (let database of databases) {
 
         for (var key in this.users) {
           var u = this.users[key]
-          expect(u.root.get('stuff')).toBeUndefined()
+          expect(u.share.root.get('stuff')).toBeUndefined()
         }
         done()
       }))
@@ -96,7 +96,7 @@ for (let database of databases) {
 
         for (var key in this.users) {
           var u = this.users[key]
-          expect(u.root.get('stuff')).toEqual('c0')
+          expect(u.share.root.get('stuff')).toEqual('c0')
         }
         done()
       }))
@@ -116,7 +116,7 @@ for (let database of databases) {
 
         for (var key in this.users) {
           var u = this.users[key]
-          expect(u.root.get('stuff')).toBeUndefined()
+          expect(u.share.root.get('stuff')).toBeUndefined()
         }
         done()
       }))
@@ -199,7 +199,7 @@ for (let database of databases) {
 
         var promises = []
         for (var u = 0; u < this.users.length; u++) {
-          promises.push(this.users[u].root.get('Map'))
+          promises.push(this.users[u].share.root.get('Map'))
         }
         this.maps = yield Promise.all(promises)
         done()
diff --git a/src/y.js b/src/y.js
index 1d3db613d250f021a215310942795a397fc54ed8..5f9cb16296872c7fda1a401fee7f4d4e0b733dbd 100644
--- a/src/y.js
+++ b/src/y.js
@@ -22,6 +22,10 @@ Y.extend = function (name, value) {
 
 Y.requestModules = requestModules
 function requestModules (modules) {
+  // determine if this module was compiled for es5 or es6 (y.js vs. y.es6)
+  // if Insert.execute is a Function, then it isnt a generator..
+  // then load the es5(.js) files..
+  var extention = Y.Struct.Insert.execute.constructor === Function ? '.js' : '.es6'
   var promises = []
   for (var i = 0; i < modules.length; i++) {
     var modulename = 'y-' + modules[i].toLowerCase()
@@ -33,7 +37,7 @@ function requestModules (modules) {
           // module does not exist
           if (typeof window !== 'undefined') {
             var imported = document.createElement('script')
-            imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + '.js'
+            imported.src = Y.sourceDir + '/' + modulename + '/' + modulename + extention
             document.head.appendChild(imported)
 
             let requireModule = {}
@@ -69,26 +73,28 @@ type DbOptions = MemoryOptions | IndexedDBOptions
 type WebRTCOptions = {
   name: 'webrtc',
   room: string
-}
+} 
 type WebsocketsClientOptions = {
   name: 'websockets-client',
   room: string
 }
 type ConnectionOptions = WebRTCOptions | WebsocketsClientOptions
 
-type TypesOptions = Array<'array'|'map'|'text'>
-
 type YOptions = {
   connector: ConnectionOptions,
   db: DbOptions,
-  types: TypesOptions,
-  sourceDir: string
+  types: Array<TypeName>,
+  sourceDir: string,
+  share: {[key: string]: TypeName}
 }
 */
 
 function Y (opts/* :YOptions */) /* :Promise<YConfig> */ {
   opts.types = opts.types != null ? opts.types : []
   var modules = [opts.db.name, opts.connector.name].concat(opts.types)
+  for (var name in opts.share) {
+    modules.push(opts.share[name])
+  }
   Y.sourceDir = opts.sourceDir
   return Y.requestModules(modules).then(function () {
     return new Promise(function (resolve) {
@@ -105,19 +111,18 @@ class YConfig {
   /* ::
   db: Y.AbstractDatabase;
   connector: Y.AbstractConnector;
+  share: {[key: string]: any};
   */
   constructor (opts, callback) {
     this.db = new Y[opts.db.name](this, opts.db)
     this.connector = new Y[opts.connector.name](this, opts.connector)
+    var share = {}
+    this.share = share
     this.db.requestTransaction(function * requestTransaction () {
-      // create initial Map type
-      this.store._temporaryUserIdGenerator = function () {
-        return ['_', 0]
+      // create shared object
+      for (var propertyname in opts.share) {
+        share[propertyname] = yield* this.getType(['_', opts.share[propertyname] + '_' + propertyname])
       }
-      var typeid = yield* Y.Map.createType.call(this)
-      var type = yield* this.getType(typeid)
-      this.store.y.root = type
-      this.store._temporaryUserIdGenerator = null
       setTimeout(callback, 0)
     })
   }