WIP

Change-Id: Iceb220498b913f832ca41dab39f5ab30676938a0
diff --git a/src/syncgroup-manager.js b/src/syncgroup-manager.js
index e471537..04befc8 100644
--- a/src/syncgroup-manager.js
+++ b/src/syncgroup-manager.js
@@ -14,9 +14,9 @@
     createSyncGroup: function(name, prefixes) {
       var self = this;
 
-      var sg = self.syncbaseWrapper.syncGroup(self.sgAdmin, name);
+      var sg = this.syncbaseWrapper.syncGroup(self.sgAdmin, name);
 
-      var mgmt = vanadium.naming.join(self.mountNames.app, 'sgmt');
+      var mgmt = vanadium.naming.join(this.mountNames.app, 'sgmt');
       var spec = sg.buildSpec(prefixes, [mgmt]);
 
       /* TODO(rosswang): Right now, duplicate Syncbase creates on
@@ -42,6 +42,10 @@
       var sg = this.syncbaseWrapper.syncGroup(
         vanadium.naming.join(naming.appMount(owner), 'sgadmin'), name);
       return sg.join();
+    },
+
+    addCollaborator: function(sgName, username) {
+      
     }
   },
 
diff --git a/src/vanadium-wrapper/syncbase-wrapper.js b/src/vanadium-wrapper/syncbase-wrapper.js
index 643c471..0b9db76 100644
--- a/src/vanadium-wrapper/syncbase-wrapper.js
+++ b/src/vanadium-wrapper/syncbase-wrapper.js
@@ -208,8 +208,12 @@
         sg.join(self.context, SG_MEMBER_INFO, chainable(cb));
       });
 
-      var setSpec = promisify(function(spec, cb) {
-          sg.setSpec(self.context, spec, '', chainable(cb));
+      var getSpec = promisify(function(cb) {
+          sg.getSpec(self.context, chainable(cb));
+      });
+
+      var setSpec = promisify(function(spec, version, cb) {
+          sg.setSpec(self.context, spec, version, chainable(cb));
       });
 
       /* Be explicit about arg lists because promisify is sensitive to extra
@@ -217,14 +221,14 @@
        * they're made by promisify, wrap them in a fn that actually takes 0
        * args. */
       sgp = {
-        buildSpec: function(prefixes, mountTables) {
+        buildSpec: function(prefixes, mountTables, admin, initialPermissions) {
           return new syncbase.nosql.SyncGroupSpec({
             perms: new Map([
-              ['Admin', {in: ['...']}],
-              ['Read', {in: ['...']}],
-              ['Write', {in: ['...']}],
-              ['Resolve', {in: ['...']}],
-              ['Debug', {in: ['...']}]
+              ['Admin', {in: [admin]}],
+              ['Read', {in: initialPermissions}],
+              ['Write', {in: initialPermissions}],
+              ['Resolve', {in: initialPermissions}],
+              ['Debug', {in: [admin]}]
             ]),
             prefixes: prefixes.map(function(p) { return 't:' + joinKey(p); }),
             mountTables: mountTables
@@ -234,17 +238,28 @@
         create: function(spec) { return create(spec); },
         destroy: function() { return destroy(); },
         join: function() { return join(); },
+        getSpec: function() { return getSpec(); },
         setSpec: function(spec) { return setSpec(spec); },
+        changeSpec: function(fn) {
+          return sgp.getSpec().then(function(versionedSpec) {
+            var spec = versionedSpec.spec;
+            return sgp.setSpec(fn(spec) || spec, versionedSpec.version)
+              .catch(function(err) {
+                if (err.id === 'v.io/v23/verror.Version') {
+                  return sgp.changeSpec(fn);
+                } else {
+                  throw err;
+                }
+              });
+          });
+        },
 
         createOrJoin: function(spec) {
           return sgp.create(spec)
             .catch(function(err) {
               if (err.id === 'v.io/v23/verror.Exist') {
                 debug.log('Syncbase: syncgroup ' + name + ' already exists.');
-                return sgp.join()
-                  .then(function() {
-                    return sgp.setSpec(spec);
-                  });
+                return sgp.join();
               } else {
                 throw err;
               }
@@ -253,9 +268,7 @@
 
         joinOrCreate: function(spec) {
           return sgp.join()
-            .then(function() {
-              return sgp.setSpec(spec);
-            }, function(err) {
+            .catch(function(err) {
               if (err.id === 'v.io/v23/verror.NoExist') {
                 debug.log('Syncbase: syncgroup ' + name + ' does not exist.');
                 return sgp.createOrJoin(spec);