Add google sign-in demo that yields default blessings

The swift project has been refactored to build two different
frameworks: Vanadium & Syncbase. The Syncbase will yield simple APIs
for a drop-in framework that masquerades much of the V23 stack.

The demo project has improved to have a picker UI, app icon & more.
It has gained an additional demo that uses the Google SignIn SDK to
obtain an oauth token, and then use that token to receive a default
blessing from dev.v.io. Currently it is using a non-Google app
setting but this can be easily swapped out in the future.

Currently private/public keys are asking V23 to store them in a
special directory under Application Support with
NSFileProtectionCompleteUntilUnlock, but in the future this will
change to keep the private key in the Apple Keychain and have
configurable security setting. Unfortunately, the environmental flags
are being read in at boot in the CGO library so we aren’t able to
pass the correct directory until the credentials flag has already been
created and loaded.

The project is also putting Alamofire and Google Sign In under the
third-party repo, but in the (short) future we’ll move to a Cocoapods
setup so we don’t have to directly check in this code.

MultiPart: 1/2
Change-Id: I6c5f7c80343ca8e92aab5daa196128a94eef2069
diff --git a/demo/Demo.xcodeproj/project.pbxproj b/demo/Demo.xcodeproj/project.pbxproj
index a7f9541..b677969 100644
--- a/demo/Demo.xcodeproj/project.pbxproj
+++ b/demo/Demo.xcodeproj/project.pbxproj
@@ -7,17 +7,143 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		30A291DD1CAC981E00F3612E /* RPCDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A291DC1CAC981E00F3612E /* RPCDemo.swift */; };
+		30A291DF1CAC982900F3612E /* Demo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A291DE1CAC982900F3612E /* Demo.swift */; };
+		30A291E11CAC996F00F3612E /* GoogleSignInDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A291E01CAC996F00F3612E /* GoogleSignInDemo.swift */; };
+		30A291F11CACB0F000F3612E /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291F01CACB0F000F3612E /* AddressBook.framework */; };
+		30A291F31CACB0F500F3612E /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291F21CACB0F500F3612E /* SafariServices.framework */; };
+		30A291F51CACB0FB00F3612E /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291F41CACB0FB00F3612E /* SystemConfiguration.framework */; };
+		30A291F71CACB13200F3612E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 30A291F61CACB13200F3612E /* GoogleService-Info.plist */; };
+		30A292021CACB46000F3612E /* GoogleSignIn.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291EB1CACB0A100F3612E /* GoogleSignIn.framework */; };
+		30A292041CACB4C300F3612E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A292031CACB4C300F3612E /* libz.tbd */; };
+		30A292051CACD40300F3612E /* GoogleSignIn.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 30A291EA1CACB0A100F3612E /* GoogleSignIn.bundle */; };
+		30A292061CADD82D00F3612E /* VanadiumCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291D11CAC97BC00F3612E /* VanadiumCore.framework */; };
+		30A292071CADD82D00F3612E /* VanadiumCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291D11CAC97BC00F3612E /* VanadiumCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		30A2920B1CADD82F00F3612E /* Syncbase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291D51CAC97BC00F3612E /* Syncbase.framework */; };
+		30A2920C1CADD82F00F3612E /* Syncbase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 30A291D51CAC97BC00F3612E /* Syncbase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		30DD1B201CB5DB9300C1A66B /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30DD1B131CB5DB8700C1A66B /* Alamofire.framework */; };
+		30DD1B211CB5DB9300C1A66B /* Alamofire.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 30DD1B131CB5DB8700C1A66B /* Alamofire.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		9306FB941BFC049400DE7190 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9306FB931BFC049400DE7190 /* AppDelegate.swift */; };
-		9306FB961BFC049400DE7190 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9306FB951BFC049400DE7190 /* ViewController.swift */; };
+		9306FB961BFC049400DE7190 /* DemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9306FB951BFC049400DE7190 /* DemoViewController.swift */; };
 		9306FB991BFC049400DE7190 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9306FB971BFC049400DE7190 /* Main.storyboard */; };
 		9306FB9B1BFC049400DE7190 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9306FB9A1BFC049400DE7190 /* Assets.xcassets */; };
 		9306FB9E1BFC049400DE7190 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9306FB9C1BFC049400DE7190 /* LaunchScreen.storyboard */; };
 		9306FBA91BFC049400DE7190 /* DemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9306FBA81BFC049400DE7190 /* DemoTests.swift */; };
-		9306FBBC1BFC04B900DE7190 /* v23.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9306FBB91BFC04AE00DE7190 /* v23.framework */; };
-		9306FBBD1BFC04B900DE7190 /* v23.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9306FBB91BFC04AE00DE7190 /* v23.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		30A291D01CAC97BC00F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 93BC21551C9E199F0074C612;
+			remoteInfo = VanadiumCore;
+		};
+		30A291D21CAC97BC00F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 93BC215F1C9E199F0074C612;
+			remoteInfo = VanadiumCoreTests;
+		};
+		30A291D41CAC97BC00F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 93B980D91CAB9D3D00CE42E0;
+			remoteInfo = Syncbase;
+		};
+		30A291D61CAC97BC00F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 93B980E21CAB9D3D00CE42E0;
+			remoteInfo = SyncbaseTests;
+		};
+		30A291D81CAC97D000F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 93BC21541C9E199F0074C612;
+			remoteInfo = VanadiumCore;
+		};
+		30A291DA1CAC97D300F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 93B980D81CAB9D3D00CE42E0;
+			remoteInfo = Syncbase;
+		};
+		30A292081CADD82D00F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 93BC21541C9E199F0074C612;
+			remoteInfo = VanadiumCore;
+		};
+		30A2920D1CADD82F00F3612E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = 93B980D81CAB9D3D00CE42E0;
+			remoteInfo = Syncbase;
+		};
+		30DD1B121CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = F8111E3319A95C8B0040E7D1;
+			remoteInfo = "Alamofire iOS";
+		};
+		30DD1B141CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = F8111E3E19A95C8B0040E7D1;
+			remoteInfo = "Alamofire iOS Tests";
+		};
+		30DD1B161CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4DD67C0B1A5C55C900ED2280;
+			remoteInfo = "Alamofire OSX";
+		};
+		30DD1B181CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = F829C6B21A7A94F100A2CD59;
+			remoteInfo = "Alamofire OSX Tests";
+		};
+		30DD1B1A1CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4CF626EF1BA7CB3E0011A099;
+			remoteInfo = "Alamofire tvOS";
+		};
+		30DD1B1C1CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4CF626F81BA7CB3E0011A099;
+			remoteInfo = "Alamofire tvOS Tests";
+		};
+		30DD1B1E1CB5DB8700C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = E4202FE01B667AA100C997FB;
+			remoteInfo = "Alamofire watchOS";
+		};
+		30DD1B221CB5DB9300C1A66B /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = F8111E3219A95C8B0040E7D1;
+			remoteInfo = "Alamofire iOS";
+		};
 		9306FBA51BFC049400DE7190 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 9306FB881BFC049400DE7190 /* Project object */;
@@ -25,37 +151,18 @@
 			remoteGlobalIDString = 9306FB8F1BFC049400DE7190;
 			remoteInfo = Demo;
 		};
-		9306FBB81BFC04AE00DE7190 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 9306FBB31BFC04AE00DE7190 /* v23.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = 939417061BF547AB00F3F996;
-			remoteInfo = v23;
-		};
-		9306FBBA1BFC04AE00DE7190 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 9306FBB31BFC04AE00DE7190 /* v23.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = 939417101BF547AB00F3F996;
-			remoteInfo = v23Tests;
-		};
-		9306FBBE1BFC04B900DE7190 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 9306FBB31BFC04AE00DE7190 /* v23.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = 939417051BF547AB00F3F996;
-			remoteInfo = v23;
-		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
-		9306FBC01BFC04B900DE7190 /* Embed Frameworks */ = {
+		30A2920A1CADD82D00F3612E /* Embed Frameworks */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 2147483647;
 			dstPath = "";
 			dstSubfolderSpec = 10;
 			files = (
-				9306FBBD1BFC04B900DE7190 /* v23.framework in Embed Frameworks */,
+				30A2920C1CADD82F00F3612E /* Syncbase.framework in Embed Frameworks */,
+				30DD1B211CB5DB9300C1A66B /* Alamofire.framework in Embed Frameworks */,
+				30A292071CADD82D00F3612E /* VanadiumCore.framework in Embed Frameworks */,
 			);
 			name = "Embed Frameworks";
 			runOnlyForDeploymentPostprocessing = 0;
@@ -63,9 +170,22 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
+		30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Vanadium.xcodeproj; path = ../lib/Vanadium.xcodeproj; sourceTree = "<group>"; };
+		30A291DC1CAC981E00F3612E /* RPCDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RPCDemo.swift; sourceTree = "<group>"; };
+		30A291DE1CAC982900F3612E /* Demo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Demo.swift; sourceTree = "<group>"; };
+		30A291E01CAC996F00F3612E /* GoogleSignInDemo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoogleSignInDemo.swift; sourceTree = "<group>"; };
+		30A291EA1CACB0A100F3612E /* GoogleSignIn.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = GoogleSignIn.bundle; path = ../../../third_party/swift/google_signin_sdk_3_0_0/GoogleSignIn.bundle; sourceTree = "<group>"; };
+		30A291EB1CACB0A100F3612E /* GoogleSignIn.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleSignIn.framework; path = ../../../third_party/swift/google_signin_sdk_3_0_0/GoogleSignIn.framework; sourceTree = "<group>"; };
+		30A291F01CACB0F000F3612E /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
+		30A291F21CACB0F500F3612E /* SafariServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SafariServices.framework; path = System/Library/Frameworks/SafariServices.framework; sourceTree = SDKROOT; };
+		30A291F41CACB0FB00F3612E /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+		30A291F61CACB13200F3612E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
+		30A291FA1CACB1D400F3612E /* Demo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Demo-Bridging-Header.h"; sourceTree = "<group>"; };
+		30A292031CACB4C300F3612E /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
+		30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Alamofire.xcodeproj; path = "../../../third_party/swift/Alamofire-3.3.0/Alamofire.xcodeproj"; sourceTree = "<group>"; };
 		9306FB901BFC049400DE7190 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		9306FB931BFC049400DE7190 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
-		9306FB951BFC049400DE7190 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
+		9306FB951BFC049400DE7190 /* DemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoViewController.swift; sourceTree = "<group>"; };
 		9306FB981BFC049400DE7190 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
 		9306FB9A1BFC049400DE7190 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		9306FB9D1BFC049400DE7190 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
@@ -73,7 +193,6 @@
 		9306FBA41BFC049400DE7190 /* DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		9306FBA81BFC049400DE7190 /* DemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoTests.swift; sourceTree = "<group>"; };
 		9306FBAA1BFC049400DE7190 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		9306FBB31BFC04AE00DE7190 /* v23.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = v23.xcodeproj; path = ../lib/v23.xcodeproj; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -81,7 +200,14 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				9306FBBC1BFC04B900DE7190 /* v23.framework in Frameworks */,
+				30A2920B1CADD82F00F3612E /* Syncbase.framework in Frameworks */,
+				30A292041CACB4C300F3612E /* libz.tbd in Frameworks */,
+				30A292021CACB46000F3612E /* GoogleSignIn.framework in Frameworks */,
+				30A292061CADD82D00F3612E /* VanadiumCore.framework in Frameworks */,
+				30A291F51CACB0FB00F3612E /* SystemConfiguration.framework in Frameworks */,
+				30A291F31CACB0F500F3612E /* SafariServices.framework in Frameworks */,
+				30A291F11CACB0F000F3612E /* AddressBook.framework in Frameworks */,
+				30DD1B201CB5DB9300C1A66B /* Alamofire.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -95,12 +221,69 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		30A291C91CAC97BC00F3612E /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				30A291D11CAC97BC00F3612E /* VanadiumCore.framework */,
+				30A291D31CAC97BC00F3612E /* VanadiumCoreTests.xctest */,
+				30A291D51CAC97BC00F3612E /* Syncbase.framework */,
+				30A291D71CAC97BC00F3612E /* SyncbaseTests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		30A291F81CACB13700F3612E /* Google Sign In */ = {
+			isa = PBXGroup;
+			children = (
+				30A291E01CAC996F00F3612E /* GoogleSignInDemo.swift */,
+				30A291F61CACB13200F3612E /* GoogleService-Info.plist */,
+			);
+			name = "Google Sign In";
+			sourceTree = "<group>";
+		};
+		30A291F91CACB14000F3612E /* Vanadium Core Demos */ = {
+			isa = PBXGroup;
+			children = (
+				30A291DC1CAC981E00F3612E /* RPCDemo.swift */,
+			);
+			name = "Vanadium Core Demos";
+			sourceTree = "<group>";
+		};
+		30A292121CAE290500F3612E /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */,
+				30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */,
+				30A291EA1CACB0A100F3612E /* GoogleSignIn.bundle */,
+				30A291F01CACB0F000F3612E /* AddressBook.framework */,
+				30A291EB1CACB0A100F3612E /* GoogleSignIn.framework */,
+				30A291F21CACB0F500F3612E /* SafariServices.framework */,
+				30A291F41CACB0FB00F3612E /* SystemConfiguration.framework */,
+				30A292031CACB4C300F3612E /* libz.tbd */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		30DD1B091CB5DB8700C1A66B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				30DD1B131CB5DB8700C1A66B /* Alamofire.framework */,
+				30DD1B151CB5DB8700C1A66B /* Alamofire iOS Tests.xctest */,
+				30DD1B171CB5DB8700C1A66B /* Alamofire.framework */,
+				30DD1B191CB5DB8700C1A66B /* Alamofire OSX Tests.xctest */,
+				30DD1B1B1CB5DB8700C1A66B /* Alamofire.framework */,
+				30DD1B1D1CB5DB8700C1A66B /* Alamofire tvOS Tests.xctest */,
+				30DD1B1F1CB5DB8700C1A66B /* Alamofire.framework */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
 		9306FB871BFC049400DE7190 = {
 			isa = PBXGroup;
 			children = (
-				9306FBB31BFC04AE00DE7190 /* v23.xcodeproj */,
 				9306FB921BFC049400DE7190 /* Demo */,
 				9306FBA71BFC049400DE7190 /* DemoTests */,
+				30A292121CAE290500F3612E /* Frameworks */,
 				9306FB911BFC049400DE7190 /* Products */,
 			);
 			sourceTree = "<group>";
@@ -118,11 +301,15 @@
 			isa = PBXGroup;
 			children = (
 				9306FB931BFC049400DE7190 /* AppDelegate.swift */,
-				9306FB951BFC049400DE7190 /* ViewController.swift */,
+				9306FB951BFC049400DE7190 /* DemoViewController.swift */,
 				9306FB971BFC049400DE7190 /* Main.storyboard */,
+				30A291DE1CAC982900F3612E /* Demo.swift */,
+				30A291F91CACB14000F3612E /* Vanadium Core Demos */,
+				30A291F81CACB13700F3612E /* Google Sign In */,
 				9306FB9A1BFC049400DE7190 /* Assets.xcassets */,
 				9306FB9C1BFC049400DE7190 /* LaunchScreen.storyboard */,
 				9306FB9F1BFC049400DE7190 /* Info.plist */,
+				30A291FA1CACB1D400F3612E /* Demo-Bridging-Header.h */,
 			);
 			path = Demo;
 			sourceTree = "<group>";
@@ -136,15 +323,6 @@
 			path = DemoTests;
 			sourceTree = "<group>";
 		};
-		9306FBB41BFC04AE00DE7190 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				9306FBB91BFC04AE00DE7190 /* v23.framework */,
-				9306FBBB1BFC04AE00DE7190 /* v23Tests.xctest */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -155,12 +333,16 @@
 				9306FB8C1BFC049400DE7190 /* Sources */,
 				9306FB8D1BFC049400DE7190 /* Frameworks */,
 				9306FB8E1BFC049400DE7190 /* Resources */,
-				9306FBC01BFC04B900DE7190 /* Embed Frameworks */,
+				30A2920A1CADD82D00F3612E /* Embed Frameworks */,
 			);
 			buildRules = (
 			);
 			dependencies = (
-				9306FBBF1BFC04B900DE7190 /* PBXTargetDependency */,
+				30A291DB1CAC97D300F3612E /* PBXTargetDependency */,
+				30A291D91CAC97D000F3612E /* PBXTargetDependency */,
+				30A292091CADD82D00F3612E /* PBXTargetDependency */,
+				30A2920E1CADD82F00F3612E /* PBXTargetDependency */,
+				30DD1B231CB5DB9300C1A66B /* PBXTargetDependency */,
 			);
 			name = Demo;
 			productName = Demo;
@@ -191,7 +373,7 @@
 		9306FB881BFC049400DE7190 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastSwiftUpdateCheck = 0710;
+				LastSwiftUpdateCheck = 0730;
 				LastUpgradeCheck = 0710;
 				ORGANIZATIONNAME = "Google Inc.";
 				TargetAttributes = {
@@ -217,8 +399,12 @@
 			projectDirPath = "";
 			projectReferences = (
 				{
-					ProductGroup = 9306FBB41BFC04AE00DE7190 /* Products */;
-					ProjectRef = 9306FBB31BFC04AE00DE7190 /* v23.xcodeproj */;
+					ProductGroup = 30DD1B091CB5DB8700C1A66B /* Products */;
+					ProjectRef = 30DD1B081CB5DB8700C1A66B /* Alamofire.xcodeproj */;
+				},
+				{
+					ProductGroup = 30A291C91CAC97BC00F3612E /* Products */;
+					ProjectRef = 30A291C81CAC97BC00F3612E /* Vanadium.xcodeproj */;
 				},
 			);
 			projectRoot = "";
@@ -230,18 +416,81 @@
 /* End PBXProject section */
 
 /* Begin PBXReferenceProxy section */
-		9306FBB91BFC04AE00DE7190 /* v23.framework */ = {
+		30A291D11CAC97BC00F3612E /* VanadiumCore.framework */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.framework;
-			path = v23.framework;
-			remoteRef = 9306FBB81BFC04AE00DE7190 /* PBXContainerItemProxy */;
+			path = VanadiumCore.framework;
+			remoteRef = 30A291D01CAC97BC00F3612E /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
-		9306FBBB1BFC04AE00DE7190 /* v23Tests.xctest */ = {
+		30A291D31CAC97BC00F3612E /* VanadiumCoreTests.xctest */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.cfbundle;
-			path = v23Tests.xctest;
-			remoteRef = 9306FBBA1BFC04AE00DE7190 /* PBXContainerItemProxy */;
+			path = VanadiumCoreTests.xctest;
+			remoteRef = 30A291D21CAC97BC00F3612E /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30A291D51CAC97BC00F3612E /* Syncbase.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Syncbase.framework;
+			remoteRef = 30A291D41CAC97BC00F3612E /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30A291D71CAC97BC00F3612E /* SyncbaseTests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = SyncbaseTests.xctest;
+			remoteRef = 30A291D61CAC97BC00F3612E /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B131CB5DB8700C1A66B /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 30DD1B121CB5DB8700C1A66B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B151CB5DB8700C1A66B /* Alamofire iOS Tests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "Alamofire iOS Tests.xctest";
+			remoteRef = 30DD1B141CB5DB8700C1A66B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B171CB5DB8700C1A66B /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 30DD1B161CB5DB8700C1A66B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B191CB5DB8700C1A66B /* Alamofire OSX Tests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "Alamofire OSX Tests.xctest";
+			remoteRef = 30DD1B181CB5DB8700C1A66B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B1B1CB5DB8700C1A66B /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 30DD1B1A1CB5DB8700C1A66B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B1D1CB5DB8700C1A66B /* Alamofire tvOS Tests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "Alamofire tvOS Tests.xctest";
+			remoteRef = 30DD1B1C1CB5DB8700C1A66B /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		30DD1B1F1CB5DB8700C1A66B /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 30DD1B1E1CB5DB8700C1A66B /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 /* End PBXReferenceProxy section */
@@ -252,6 +501,8 @@
 			buildActionMask = 2147483647;
 			files = (
 				9306FB9E1BFC049400DE7190 /* LaunchScreen.storyboard in Resources */,
+				30A292051CACD40300F3612E /* GoogleSignIn.bundle in Resources */,
+				30A291F71CACB13200F3612E /* GoogleService-Info.plist in Resources */,
 				9306FB9B1BFC049400DE7190 /* Assets.xcassets in Resources */,
 				9306FB991BFC049400DE7190 /* Main.storyboard in Resources */,
 			);
@@ -271,8 +522,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				9306FB961BFC049400DE7190 /* ViewController.swift in Sources */,
+				30A291E11CAC996F00F3612E /* GoogleSignInDemo.swift in Sources */,
+				9306FB961BFC049400DE7190 /* DemoViewController.swift in Sources */,
 				9306FB941BFC049400DE7190 /* AppDelegate.swift in Sources */,
+				30A291DF1CAC982900F3612E /* Demo.swift in Sources */,
+				30A291DD1CAC981E00F3612E /* RPCDemo.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -287,16 +541,36 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+		30A291D91CAC97D000F3612E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = VanadiumCore;
+			targetProxy = 30A291D81CAC97D000F3612E /* PBXContainerItemProxy */;
+		};
+		30A291DB1CAC97D300F3612E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = Syncbase;
+			targetProxy = 30A291DA1CAC97D300F3612E /* PBXContainerItemProxy */;
+		};
+		30A292091CADD82D00F3612E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = VanadiumCore;
+			targetProxy = 30A292081CADD82D00F3612E /* PBXContainerItemProxy */;
+		};
+		30A2920E1CADD82F00F3612E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = Syncbase;
+			targetProxy = 30A2920D1CADD82F00F3612E /* PBXContainerItemProxy */;
+		};
+		30DD1B231CB5DB9300C1A66B /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "Alamofire iOS";
+			targetProxy = 30DD1B221CB5DB9300C1A66B /* PBXContainerItemProxy */;
+		};
 		9306FBA61BFC049400DE7190 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 9306FB8F1BFC049400DE7190 /* Demo */;
 			targetProxy = 9306FBA51BFC049400DE7190 /* PBXContainerItemProxy */;
 		};
-		9306FBBF1BFC04B900DE7190 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = v23;
-			targetProxy = 9306FBBE1BFC04B900DE7190 /* PBXContainerItemProxy */;
-		};
 /* End PBXTargetDependency section */
 
 /* Begin PBXVariantGroup section */
@@ -339,6 +613,7 @@
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
 				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_BITCODE = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -355,7 +630,7 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = iphoneos;
@@ -384,6 +659,7 @@
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_BITCODE = NO;
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -394,7 +670,7 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = iphoneos;
 				TARGETED_DEVICE_FAMILY = "1,2";
@@ -406,11 +682,20 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
 				EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
+				FRAMEWORK_SEARCH_PATHS = "${PROJECT_DIR}/../../../third_party/swift/google_signin_sdk_3_0_0";
 				INFOPLIST_FILE = Demo/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				PRODUCT_BUNDLE_IDENTIFIER = v.io.Demo;
+				OTHER_LDFLAGS = (
+					"$(OTHER_LDFLAGS)",
+					"-ObjC",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = v.io.EmpiricalDemo;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Demo/Demo-Bridging-Header.h";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				TARGETED_DEVICE_FAMILY = 1;
 			};
 			name = Debug;
 		};
@@ -418,11 +703,19 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
 				EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
+				FRAMEWORK_SEARCH_PATHS = "${PROJECT_DIR}/../../../third_party/swift/google_signin_sdk_3_0_0";
 				INFOPLIST_FILE = Demo/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
-				PRODUCT_BUNDLE_IDENTIFIER = v.io.Demo;
+				OTHER_LDFLAGS = (
+					"$(OTHER_LDFLAGS)",
+					"-ObjC",
+				);
+				PRODUCT_BUNDLE_IDENTIFIER = v.io.EmpiricalDemo;
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "Demo/Demo-Bridging-Header.h";
+				TARGETED_DEVICE_FAMILY = 1;
 			};
 			name = Release;
 		};
diff --git a/demo/Demo/AppDelegate.swift b/demo/Demo/AppDelegate.swift
index a53aa03..7e96af9 100644
--- a/demo/Demo/AppDelegate.swift
+++ b/demo/Demo/AppDelegate.swift
@@ -6,15 +6,20 @@
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
-
   var window: UIWindow?
 
-
   func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
     // Override point for customization after application launch.
     return true
   }
 
+  func application(application: UIApplication,
+                   openURL url: NSURL, options: [String: AnyObject]) -> Bool {
+    return GIDSignIn.sharedInstance().handleURL(url,
+      sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String,
+      annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
+  }
+
   func applicationWillResignActive(application: UIApplication) {
     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
@@ -36,7 +41,5 @@
   func applicationWillTerminate(application: UIApplication) {
     // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
   }
-
-
 }
 
diff --git a/demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json b/demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json
index 36d2c80..4629c36 100644
--- a/demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -21,13 +21,15 @@
       "scale" : "3x"
     },
     {
-      "idiom" : "iphone",
       "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "app-icon@2x.png",
       "scale" : "2x"
     },
     {
-      "idiom" : "iphone",
       "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "app-icon@3x.png",
       "scale" : "3x"
     },
     {
@@ -59,6 +61,11 @@
       "idiom" : "ipad",
       "size" : "76x76",
       "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "83.5x83.5",
+      "scale" : "2x"
     }
   ],
   "info" : {
diff --git a/demo/Demo/Assets.xcassets/AppIcon.appiconset/app-icon@2x.png b/demo/Demo/Assets.xcassets/AppIcon.appiconset/app-icon@2x.png
new file mode 100644
index 0000000..19eaa87
--- /dev/null
+++ b/demo/Demo/Assets.xcassets/AppIcon.appiconset/app-icon@2x.png
Binary files differ
diff --git a/demo/Demo/Assets.xcassets/AppIcon.appiconset/app-icon@3x.png b/demo/Demo/Assets.xcassets/AppIcon.appiconset/app-icon@3x.png
new file mode 100644
index 0000000..7f064bf
--- /dev/null
+++ b/demo/Demo/Assets.xcassets/AppIcon.appiconset/app-icon@3x.png
Binary files differ
diff --git a/demo/Demo/Assets.xcassets/Contents.json b/demo/Demo/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/demo/Demo/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/demo/Demo/Assets.xcassets/v23-icon-white.imageset/Contents.json b/demo/Demo/Assets.xcassets/v23-icon-white.imageset/Contents.json
new file mode 100644
index 0000000..5bd0a71
--- /dev/null
+++ b/demo/Demo/Assets.xcassets/v23-icon-white.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "v23-icon-white@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/demo/Demo/Assets.xcassets/v23-icon-white.imageset/v23-icon-white@2x.png b/demo/Demo/Assets.xcassets/v23-icon-white.imageset/v23-icon-white@2x.png
new file mode 100644
index 0000000..42fb8ae
--- /dev/null
+++ b/demo/Demo/Assets.xcassets/v23-icon-white.imageset/v23-icon-white@2x.png
Binary files differ
diff --git a/demo/Demo/Base.lproj/LaunchScreen.storyboard b/demo/Demo/Base.lproj/LaunchScreen.storyboard
index f70f059..f8d231b 100644
--- a/demo/Demo/Base.lproj/LaunchScreen.storyboard
+++ b/demo/Demo/Base.lproj/LaunchScreen.storyboard
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
     </dependencies>
     <scenes>
         <!--View Controller-->
@@ -16,8 +16,20 @@
                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <animations/>
-                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                        <subviews>
+                            <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="v23-icon-white" translatesAutoresizingMaskIntoConstraints="NO" id="rUI-LN-NJl">
+                                <rect key="frame" x="220" y="220" width="160" height="160"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="160" id="Em8-rc-Ydu"/>
+                                    <constraint firstAttribute="width" constant="160" id="G6N-RP-ygP"/>
+                                </constraints>
+                            </imageView>
+                        </subviews>
+                        <color key="backgroundColor" red="0.066666666666666666" green="0.52549019607843139" blue="0.58823529411764708" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstItem="rUI-LN-NJl" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="duR-lO-fok"/>
+                            <constraint firstItem="rUI-LN-NJl" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="pHC-oa-9W3"/>
+                        </constraints>
                     </view>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -25,4 +37,7 @@
             <point key="canvasLocation" x="53" y="375"/>
         </scene>
     </scenes>
+    <resources>
+        <image name="v23-icon-white" width="320" height="320"/>
+    </resources>
 </document>
diff --git a/demo/Demo/Base.lproj/Main.storyboard b/demo/Demo/Base.lproj/Main.storyboard
index 3a2a49b..932115b 100644
--- a/demo/Demo/Base.lproj/Main.storyboard
+++ b/demo/Demo/Base.lproj/Main.storyboard
@@ -1,25 +1,157 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="15d-HP-TF3">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
     </dependencies>
     <scenes>
-        <!--View Controller-->
-        <scene sceneID="tne-QT-ifu">
+        <!--Google Sign In Demo-->
+        <scene sceneID="Hgr-13-GMH">
             <objects>
-                <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
+                <viewController title="Google Sign In Demo" id="8TU-wk-63a" customClass="GoogleSignInDemo" customModule="Demo" customModuleProvider="target" sceneMemberID="viewController">
                     <layoutGuides>
-                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
-                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                        <viewControllerLayoutGuide type="top" id="MR1-FP-sSo"/>
+                        <viewControllerLayoutGuide type="bottom" id="tfN-75-F8Y"/>
                     </layoutGuides>
-                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                    <view key="view" contentMode="scaleToFill" id="u09-Ag-jpU">
                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ndt-M5-a4a" customClass="GIDSignInButton">
+                                <rect key="frame" x="144" y="512" width="312" height="48"/>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="312" id="0wY-RG-RRb"/>
+                                    <constraint firstAttribute="height" constant="48" id="dF6-ny-qHf"/>
+                                </constraints>
+                                <connections>
+                                    <action selector="signInClicked:" destination="8TU-wk-63a" eventType="valueChanged" id="y4A-mj-Ghn"/>
+                                </connections>
+                            </view>
+                            <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="v23-icon-white" translatesAutoresizingMaskIntoConstraints="NO" id="OuH-Zv-fPN">
+                                <rect key="frame" x="220" y="220" width="160" height="160"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="160" id="EA7-Lf-wIG"/>
+                                    <constraint firstAttribute="width" constant="160" id="EPR-vP-4Sh"/>
+                                </constraints>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fpo-3d-9vU">
+                                <rect key="frame" x="30" y="512" width="560" height="0.0"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" red="0.066666666669999999" green="0.52549019610000003" blue="0.58823529409999997" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstItem="OuH-Zv-fPN" firstAttribute="centerX" secondItem="u09-Ag-jpU" secondAttribute="centerX" id="CXn-pE-Kkd"/>
+                            <constraint firstItem="ndt-M5-a4a" firstAttribute="top" secondItem="fpo-3d-9vU" secondAttribute="bottom" id="Df6-wr-seA"/>
+                            <constraint firstItem="fpo-3d-9vU" firstAttribute="leading" secondItem="u09-Ag-jpU" secondAttribute="leadingMargin" constant="10" id="Ixz-qQ-jIh"/>
+                            <constraint firstItem="OuH-Zv-fPN" firstAttribute="centerY" secondItem="u09-Ag-jpU" secondAttribute="centerY" id="OEL-7A-Etb"/>
+                            <constraint firstItem="ndt-M5-a4a" firstAttribute="centerX" secondItem="u09-Ag-jpU" secondAttribute="centerX" id="WjZ-X6-olq"/>
+                            <constraint firstItem="fpo-3d-9vU" firstAttribute="trailing" secondItem="u09-Ag-jpU" secondAttribute="trailingMargin" constant="10" id="cUB-wf-NSv"/>
+                            <constraint firstItem="tfN-75-F8Y" firstAttribute="top" secondItem="ndt-M5-a4a" secondAttribute="bottom" constant="40" id="pdh-aG-wHG"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="signInButton" destination="ndt-M5-a4a" id="Jyd-ag-upy"/>
+                        <outlet property="statusLabel" destination="fpo-3d-9vU" id="AbD-30-7B2"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="EUE-7A-7S3" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="654" y="-823"/>
+        </scene>
+        <!--Demos-->
+        <scene sceneID="o8K-Q4-OW7">
+            <objects>
+                <tableViewController title="Demos" id="j6k-Fl-n3R" customClass="DemoViewController" customModule="Demo" customModuleProvider="target" sceneMemberID="viewController">
+                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="gIT-ZK-by2">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <prototypes>
+                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="DemoNameCells" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DemoNameCells" textLabel="Pqo-lf-iHB" style="IBUITableViewCellStyleDefault" id="eMk-7N-VeI">
+                                <rect key="frame" x="0.0" y="92" width="600" height="44"/>
+                                <autoresizingMask key="autoresizingMask"/>
+                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="eMk-7N-VeI" id="zOH-mh-gvr">
+                                    <rect key="frame" x="0.0" y="0.0" width="567" height="43.5"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <subviews>
+                                        <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Pqo-lf-iHB">
+                                            <rect key="frame" x="15" y="0.0" width="550" height="43.5"/>
+                                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                                            <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                                            <nil key="highlightedColor"/>
+                                        </label>
+                                    </subviews>
+                                </tableViewCellContentView>
+                            </tableViewCell>
+                        </prototypes>
+                        <connections>
+                            <outlet property="dataSource" destination="j6k-Fl-n3R" id="jXE-1C-FNq"/>
+                            <outlet property="delegate" destination="j6k-Fl-n3R" id="cDg-gP-dgr"/>
+                        </connections>
+                    </tableView>
+                    <navigationItem key="navigationItem" title="Demos" id="20e-LI-k33"/>
+                    <connections>
+                        <segue destination="BV7-jR-rDh" kind="show" identifier="RPCDemo" id="3ch-Dh-9Ah"/>
+                        <segue destination="8TU-wk-63a" kind="show" identifier="GoogleSignInDemo" id="eZj-zG-Lbo"/>
+                    </connections>
+                </tableViewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="OQS-6w-6FP" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1056" y="269"/>
+        </scene>
+        <!--RPC Demo-->
+        <scene sceneID="Zk7-If-Oyb">
+            <objects>
+                <viewController title="RPC Demo" id="BV7-jR-rDh" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="Gg1-8I-HxU"/>
+                        <viewControllerLayoutGuide type="bottom" id="E0S-a1-x1p"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="QqW-Hd-lXw">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="RPC Demo is in console" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vhQ-hW-SP4">
+                                <rect key="frame" x="209.5" y="289" width="181.5" height="21"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="vhQ-hW-SP4" firstAttribute="centerX" secondItem="QqW-Hd-lXw" secondAttribute="centerX" id="5PI-tW-8e5"/>
+                            <constraint firstItem="vhQ-hW-SP4" firstAttribute="centerY" secondItem="QqW-Hd-lXw" secondAttribute="centerY" id="RMv-dU-zak"/>
+                        </constraints>
                     </view>
                 </viewController>
-                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="K2H-Mp-r9g" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
+            <point key="canvasLocation" x="654" y="1144"/>
+        </scene>
+        <!--Vanadium-->
+        <scene sceneID="DQO-5c-O5y">
+            <objects>
+                <navigationController title="Vanadium" id="15d-HP-TF3" sceneMemberID="viewController">
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" id="gMf-Oe-60N">
+                        <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </navigationBar>
+                    <connections>
+                        <segue destination="j6k-Fl-n3R" kind="relationship" relationship="rootViewController" id="71R-HV-CKE"/>
+                    </connections>
+                </navigationController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="SnP-Ps-3nA" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="112" y="269"/>
         </scene>
     </scenes>
+    <resources>
+        <image name="v23-icon-white" width="320" height="320"/>
+    </resources>
 </document>
diff --git a/demo/Demo/Demo-Bridging-Header.h b/demo/Demo/Demo-Bridging-Header.h
new file mode 100644
index 0000000..e29435b
--- /dev/null
+++ b/demo/Demo/Demo-Bridging-Header.h
@@ -0,0 +1,5 @@
+//
+//  Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#import <GoogleSignIn/GoogleSignIn.h>
\ No newline at end of file
diff --git a/demo/Demo/Demo.swift b/demo/Demo/Demo.swift
new file mode 100644
index 0000000..ba45c03
--- /dev/null
+++ b/demo/Demo/Demo.swift
@@ -0,0 +1,14 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import UIKit
+
+protocol DemoDescription : CustomStringConvertible {
+  var segue: String { get }
+  var instance: Demo { get }
+}
+
+protocol Demo {
+  mutating func start()
+}
diff --git a/demo/Demo/DemoViewController.swift b/demo/Demo/DemoViewController.swift
new file mode 100644
index 0000000..a54d746
--- /dev/null
+++ b/demo/Demo/DemoViewController.swift
@@ -0,0 +1,44 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import UIKit
+import VanadiumCore
+
+class DemoViewController: UITableViewController {
+  let demos:[DemoDescription] = [RPCDemoDescription(), GoogleSignInDemoDescription()]
+  var currentDemo:Demo? = nil
+
+  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+    return demos.count
+  }
+
+  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+    if indexPath.row >= demos.count {
+      return mkErrorCell(indexPath)
+    }
+    guard let cell = tableView.dequeueReusableCellWithIdentifier("DemoNameCells") else {
+      return mkErrorCell(indexPath)
+    }
+    let demo = demos[indexPath.row]
+    cell.textLabel?.text = demo.description
+    return cell
+  }
+
+  private func mkErrorCell(indexPath: NSIndexPath) -> UITableViewCell {
+    let cell = UITableViewCell(style: .Default, reuseIdentifier: "error")
+    cell.textLabel?.text = "Error for index path \(indexPath)"
+    return cell
+  }
+
+  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
+    let demo = demos[indexPath.row]
+    currentDemo = demo.instance
+    performSegueWithIdentifier(demo.segue, sender: self)
+  }
+
+  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
+    // Starts any non-UI demos
+    currentDemo?.start()
+  }
+}
diff --git a/demo/Demo/GoogleService-Info.plist b/demo/Demo/GoogleService-Info.plist
new file mode 100644
index 0000000..1487cb9
--- /dev/null
+++ b/demo/Demo/GoogleService-Info.plist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CLIENT_ID</key>
+	<string>613002262434-kbdv4copi6p6b9a91mffoa1jittbcpt4.apps.googleusercontent.com</string>
+	<key>REVERSED_CLIENT_ID</key>
+	<string>com.googleusercontent.apps.613002262434-kbdv4copi6p6b9a91mffoa1jittbcpt4</string>
+	<key>PLIST_VERSION</key>
+	<string>1</string>
+	<key>BUNDLE_ID</key>
+	<string>v.io.EmpiricalDemo</string>
+	<key>IS_ADS_ENABLED</key>
+	<false/>
+	<key>IS_ANALYTICS_ENABLED</key>
+	<false/>
+	<key>IS_APPINVITE_ENABLED</key>
+	<false/>
+	<key>IS_GCM_ENABLED</key>
+	<false/>
+	<key>IS_SIGNIN_ENABLED</key>
+	<true/>
+	<key>GOOGLE_APP_ID</key>
+	<string>1:613002262434:ios:ee98fd5d653b1ab5</string>
+	<key>PROJECT_ID</key>
+	<string>vanadium-demo</string>
+</dict>
+</plist>
\ No newline at end of file
diff --git a/demo/Demo/GoogleSignInDemo.swift b/demo/Demo/GoogleSignInDemo.swift
new file mode 100644
index 0000000..76c1e2a
--- /dev/null
+++ b/demo/Demo/GoogleSignInDemo.swift
@@ -0,0 +1,111 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import UIKit
+import Syncbase
+import VanadiumCore
+
+struct GoogleSignInDemoDescription : DemoDescription {
+  let segue: String = "GoogleSignInDemo"
+
+  var description: String {
+    return "Google Sign-In Demo"
+  }
+
+  var instance: Demo {
+    return GoogleSignInDemo()
+  }
+}
+
+@objc class GoogleSignInDemo : UIViewController, Demo, GIDSignInDelegate, GIDSignInUIDelegate {
+  @IBOutlet weak var signInButton: GIDSignInButton!
+  @IBOutlet weak var statusLabel: UILabel!
+
+  override func viewDidLoad() {
+    super.viewDidLoad()
+    statusLabel.text = ""
+    configureGoogle()
+  }
+
+  func start() {
+    // We have to configureGoogle() on viewDidLoad as the Google Sign In's delegates (self) are
+    // not fully initialized at this point. This start call is more useful for non-UI-based demos.
+  }
+
+  func configureGoogle() {
+    // Pull client_id out of the GoogleService-Info plist
+    let plistUrl = NSBundle.mainBundle().URLForResource("GoogleService-Info", withExtension: "plist")!
+    let servicePlist = NSDictionary(contentsOfURL: plistUrl)!
+    let clientId = servicePlist["CLIENT_ID"] as! String
+    // Initialize sign-in
+    GIDSignIn.sharedInstance().clientID = clientId
+    GIDSignIn.sharedInstance().delegate = self
+    GIDSignIn.sharedInstance().uiDelegate = self
+    // Style
+    signInButton.style = .Wide
+  }
+
+  func signIn(signIn: GIDSignIn!, presentViewController viewController: UIViewController!) {
+    self.presentViewController(viewController, animated: true) {
+      debugPrint("Presented google sign in")
+    }
+  }
+
+  func signIn(signIn: GIDSignIn!, dismissViewController viewController: UIViewController!) {
+    self.dismissViewControllerAnimated(true) {
+      debugPrint("Dismissed sign on")
+    }
+  }
+
+  func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!, withError error: NSError!) {
+    // Handle errors
+    guard error == nil else {
+      debugPrint("Error signing in: \(error)")
+      statusLabel.text = "Error signing in: \(error)"
+      return
+    }
+    guard user != nil else {
+      debugPrint("Error signing in: couldn't get user object")
+      statusLabel.text = "Error signing in: couldn't get user object"
+      return
+    }
+    // Get or refresh oauth access token
+    weak var this = self
+    user.authentication.getTokensWithHandler { (auth, error) in
+      guard error == nil else {
+        debugPrint("Error getting auth token: \(error)")
+        this?.statusLabel.text = "Error getting auth token: \(error)"
+        return
+      }
+      this?.didSignIn(user, auth: auth)
+    }
+  }
+
+  func didSignIn(user:GIDGoogleUser, auth:GIDAuthentication) {
+    signInButton.hidden = true
+
+    let oauthToken = auth.accessToken
+    let userId = user.userID
+    let userEmail = user.profile.email
+
+    debugPrint("Signed in \(userEmail) (\(userId)) with oauth token \(oauthToken)")
+    statusLabel.text = "Signed in \(userEmail)... getting blessing"
+    getBlessing(oauthToken)
+  }
+
+  func getBlessing(oauthToken:String) {
+    weak var this = self
+    let credentials = GoogleCredentials(oauthToken: oauthToken)
+    credentials.authorize()
+      .onReject { err in
+        debugPrint("Unable to get blessing: \(err)")
+        this?.statusLabel.text = "Unable to get blessing: \(err)"
+      }
+      .onResolve { _ in
+        let blessings:String! = try? Principal.blessingsDebugString() ?? "<error>"
+        debugPrint("Got blessings \(blessings)")
+        this?.statusLabel.text = "Got blessing: \(blessings)"
+      }
+  }
+}
diff --git a/demo/Demo/Info.plist b/demo/Demo/Info.plist
index 40c6215..2c76b55 100644
--- a/demo/Demo/Info.plist
+++ b/demo/Demo/Info.plist
@@ -18,6 +18,27 @@
 	<string>1.0</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLName</key>
+			<string></string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>com.googleusercontent.apps.613002262434-kbdv4copi6p6b9a91mffoa1jittbcpt4</string>
+			</array>
+		</dict>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>v.io.EmpiricalDemo</string>
+			</array>
+		</dict>
+	</array>
 	<key>CFBundleVersion</key>
 	<string>1</string>
 	<key>LSRequiresIPhoneOS</key>
@@ -33,8 +54,6 @@
 	<key>UISupportedInterfaceOrientations</key>
 	<array>
 		<string>UIInterfaceOrientationPortrait</string>
-		<string>UIInterfaceOrientationLandscapeLeft</string>
-		<string>UIInterfaceOrientationLandscapeRight</string>
 	</array>
 	<key>UISupportedInterfaceOrientations~ipad</key>
 	<array>
diff --git a/demo/Demo/ViewController.swift b/demo/Demo/RPCDemo.swift
similarity index 84%
rename from demo/Demo/ViewController.swift
rename to demo/Demo/RPCDemo.swift
index 6a95b67..e8961dc 100644
--- a/demo/Demo/ViewController.swift
+++ b/demo/Demo/RPCDemo.swift
@@ -3,39 +3,46 @@
 // license that can be found in the LICENSE file.
 
 import UIKit
-import v23
+import VanadiumCore
 
-class ViewController: UIViewController {
-  override func viewDidLoad() {
-    super.viewDidLoad()
+struct RPCDemoDescription : DemoDescription {
+  let segue:String = "RPCDemo"
+
+  var description: String {
+    return "RPC Demo"
+  }
+
+  var instance: Demo {
+    return RPCDemo()
+  }
+}
+
+struct RPCDemo : Demo {
+  mutating func start() {
     startVanadium()
     testHelloCall()
     testCancel()
   }
 
-  override func didReceiveMemoryWarning() {
-    super.didReceiveMemoryWarning()
-  }
-
   let addr = "/" + "@6@wsh@100.110.93.71:23000@@b6752aa9f33f86b9aecf25ecad73c8a4@l@tutorial@@"
   var instance:V23? = nil
 
-  func startVanadium() {
+  mutating func startVanadium() {
     do {
-      try v23.configure()
-      instance = v23.instance
+      try V23.configure()
+      instance = V23.instance
     } catch let e as VError {
       print("Got a verror:", e)
     } catch let e {
       print("Got an exception:", e)
     }
   }
-  
+
   func testHelloCall() {
     var ctx = instance!.context
     ctx.deadline = NSDate(timeIntervalSinceNow: 1)
     print("Calling startCall")
-    
+
     do {
       let client = try ctx.client()
       client.call(name: addr, method: "Get", args: nil, returnArgsLength: 1, skipServerAuth: true)
@@ -56,7 +63,7 @@
     var ctx = instance!.context
     ctx.isCancellable = true
     print("Calling startCall")
-    
+
     do {
       let client = try ctx.client()
       client.call(name: addr, method: "Get", args: nil, returnArgsLength: 1, skipServerAuth: true)
@@ -72,7 +79,7 @@
         }
         .onReject { err -> () in
           print("Cancel errored with \(err)")
-        }
+      }
     } catch let e as VError {
       print("Got an unexpected verror:", e)
     } catch let e {
@@ -80,4 +87,3 @@
     }
   }
 }
-
diff --git a/demo/README.md b/demo/README.md
new file mode 100644
index 0000000..6a37d55
--- /dev/null
+++ b/demo/README.md
@@ -0,0 +1,71 @@
+#Vanadium Swift Demos
+
+## STATUS
+The Vanadium Swift implementation is very iOS/OS X specific at this point,
+especially since the open source release Linux is very early as of this writing
+(April 2016).
+
+Currently the following are included in the iOS demo:
+
+- "Hello world" RPC with a hard coded endpoint (discovery coming soon)
+	 
+- Google Sign-In OAuth used to obtain a default blessing via
+	   dev.v.io.
+
+Requires Swift 2.2 which is available in Xcode 7.3. Any earlier versions won't
+compile, and a later version of Swift will also likely cause a problem as well.
+
+The demo also targets iOS 9.0+, although the Vanadium libraries target 8.0+
+
+There are two Vanadium frameworks that the demo uses:
+
+- VanadiumCore.framework - This is the Swift bridge to the V23 runtime. It is intended for full Vanadium development, such as performing RPC and manual discovery management.
+
+- Syncbase.framework - This is the simple & high-level framework that abstracts away VanadiumCore and exposes a direct Swift API for Syncbase. We intend most apps will only need to work with APIs in Syncbase.framework for the near-future.
+
+Eventually we will also support Cocoapods, but until then it is required that a checkout of Vanadium is done correctly across multiple-repositories as Demo/VanadiumCore/Syncbase rely on code in the third-party repo separate from this swift-repo.
+
+## INSTRUCTIONS
+The repo does not include any of the built CGO libraries or header files.
+These must be built before the demo may be compiled and run.
+
+### Build the cross-compile iOS Go
+In order to compile the CGO library for the iOS platform, we need to install a cross-compiling version of go first. It's important to do this for all supported platforms even if you're only planning on compiling for the simulator, because our Xcode project expects to see files for all architectures (they can be kept out of sync while developing, however). 
+
+Install the 64-bit simulator Go profile:
+
+	jiri profile install -target amd64-ios v23:base
+
+Install the 64-bit device Go profile:
+
+	jiri profile install -target arm64-ios v23:base
+
+
+### To compile the CGO static libraries
+For simulator only (these are equivalent)
+
+	jiri-swift build build-cgo	
+	# or
+	jiri-swift build -target amd64 build-cgo	
+
+For device: 
+
+	jiri-swift build -target arm64 build-cgo
+
+For both:
+
+	jiri-swift build -target all build-cgo
+
+
+### To run the demos via Xcode (standard instructions)
+
+1. Double click the Demo.xcodeproj to Xcode and open the project.
+2. Make sure the Demo scheme is selected (it may already be), and choose the
+   appropriate device (either a 64-bit simulator like the iPhone 5s or a
+   plugged in 64-bit iPhone... 32-bit iPhone 5 & 4s is not supported currently).
+   If you are unfamiliar with Xcode, look in the upper left of the project
+   window and you'll see next to the Play and Stop icons a two part drop-down
+   menu... the first one selects the target (chose Demo) and the second part
+   selects the device (the iPhone 5S and later are 64-bit).
+3. Run the project either via the menu Product > Run or the Play button in the
+   upper left.
\ No newline at end of file
diff --git a/lib/Syncbase/Info.plist b/lib/Syncbase/Info.plist
new file mode 100644
index 0000000..d3de8ee
--- /dev/null
+++ b/lib/Syncbase/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>$(CURRENT_PROJECT_VERSION)</string>
+	<key>NSPrincipalClass</key>
+	<string></string>
+</dict>
+</plist>
diff --git a/lib/Syncbase/Security.swift b/lib/Syncbase/Security.swift
new file mode 100644
index 0000000..34e1d8d
--- /dev/null
+++ b/lib/Syncbase/Security.swift
@@ -0,0 +1,90 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import Foundation
+
+import Alamofire
+import VanadiumCore
+
+public protocol VanadiumBlesser {
+  func blessingsFromGoogle(googleOauthToken:String) -> Promise<NSData>
+}
+
+enum VanadiumUrls : String, URLStringConvertible {
+  case DevBlessings = "https://dev.v.io/auth/google/bless"
+
+  var URLString: String {
+    return self.rawValue.URLString
+  }
+}
+
+enum BlessingOutputFormat : String {
+  case Base64VOM = "base64vom"
+}
+
+public enum VanadiumBlesserError : ErrorType {
+  case EmptyResult
+  case NotBase64Encoded(invalid:String)
+}
+
+public extension VanadiumBlesser {
+  public func blessingsFromGoogle(googleOauthToken:String) -> Promise<NSData> {
+    // Make sure the Syncbase instance exists, which inits V23
+    let _ = Syncbase.instance
+    let p = Promise<NSData>()
+    do {
+      let params:[String:AnyObject] = [
+          "token": googleOauthToken,
+          "public_key": try VanadiumCore.Principal.publicKey(),
+          "output_format": BlessingOutputFormat.Base64VOM.rawValue]
+      let request = Alamofire.request(.GET,
+                        VanadiumUrls.DevBlessings,
+                        parameters: params,
+                        encoding: ParameterEncoding.URLEncodedInURL,
+                        headers:nil)
+      request.responseString { resp in
+        guard let base64 = resp.result.value else {
+          if let err = resp.result.error {
+            try! p.reject(err)
+          } else {
+            try! p.reject(VanadiumBlesserError.EmptyResult)
+          }
+          return
+        }
+
+        // The base64 values are encoded using Go's URL-variant of base64 encoding, which is not
+        // compatible with Apple's base64 encoder/decoder. So we call out to to Go directly to
+        // decode this value into the vom-encoded byte array.
+        let swiftArray = swift_io_v_swift_impl_util_type_nativeBase64UrlDecode(base64.toGo())
+        if swiftArray.length == 0 {
+          try! p.reject(VanadiumBlesserError.NotBase64Encoded(invalid: base64))
+          return
+        }
+        let data = swiftArray.toNSDataNoCopyFreeWhenDone()
+        try! p.resolve(data)
+      }
+    } catch let err {
+      try! p.reject(err)
+    }
+    return p
+  }
+}
+
+public protocol OAuthCredentials {
+  var oauthToken:String { get }
+}
+
+public struct GoogleCredentials : OAuthCredentials, VanadiumBlesser {
+  public let oauthToken: String
+
+  public init(oauthToken: String) {
+    self.oauthToken = oauthToken
+  }
+
+  public func authorize() -> Promise<Void> {
+    return blessingsFromGoogle(oauthToken).thenInBackground { blessings in
+      try VanadiumCore.Principal.setBlessings(blessings)
+    }
+  }
+}
diff --git a/lib/Syncbase/Syncbase.h b/lib/Syncbase/Syncbase.h
new file mode 100644
index 0000000..514ed51
--- /dev/null
+++ b/lib/Syncbase/Syncbase.h
@@ -0,0 +1,11 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+
+//! Project version number for Syncbase.
+FOUNDATION_EXPORT double SyncbaseVersionNumber;
+
+//! Project version string for Syncbase.
+FOUNDATION_EXPORT const unsigned char SyncbaseVersionString[];
diff --git a/lib/Syncbase/Syncbase.swift b/lib/Syncbase/Syncbase.swift
new file mode 100644
index 0000000..66056f0
--- /dev/null
+++ b/lib/Syncbase/Syncbase.swift
@@ -0,0 +1,46 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import Foundation
+
+import VanadiumCore
+
+public let instance = Syncbase.instance
+
+public class Syncbase {
+  private static var _instance: Syncbase? = nil
+
+  /// The singleton instance of Syncbase. This is the primary class that houses the simplified
+  /// API.
+  ///
+  /// You won't be able to sync with anybody unless you grant yourself a blessing via the authorize
+  /// method.
+  public static var instance: Syncbase {
+    get {
+      if (_instance == nil) {
+        do {
+          _instance = try Syncbase()
+        } catch let err {
+          VanadiumCore.log.warning("Couldn't instantiate an instance of Syncbase: \(err)")
+        }
+      }
+      return _instance!
+    }
+    set {
+      if (_instance != nil) {
+        fatalError("You cannot create another instance of V23")
+      }
+      _instance = newValue
+    }
+  }
+
+  /// Private constructor for V23.
+  private init() throws {
+    try V23.configure()
+  }
+
+  deinit {
+
+  }
+}
diff --git a/lib/SyncbaseTests/Info.plist b/lib/SyncbaseTests/Info.plist
new file mode 100644
index 0000000..ba72822
--- /dev/null
+++ b/lib/SyncbaseTests/Info.plist
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>
diff --git a/lib/SyncbaseTests/SyncbaseTests.swift b/lib/SyncbaseTests/SyncbaseTests.swift
new file mode 100644
index 0000000..08a20f0
--- /dev/null
+++ b/lib/SyncbaseTests/SyncbaseTests.swift
@@ -0,0 +1,18 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import XCTest
+@testable import Syncbase
+
+class SyncbaseTests: XCTestCase {
+  override func setUp() {
+    super.setUp()
+    // Put setup code here. This method is called before the invocation of each test method in the class.
+  }
+
+  override func tearDown() {
+    // Put teardown code here. This method is called after the invocation of each test method in the class.
+    super.tearDown()
+  }
+}
diff --git a/lib/Vanadium.xcodeproj/project.pbxproj b/lib/Vanadium.xcodeproj/project.pbxproj
index cb9a633..5c3f4a2 100644
--- a/lib/Vanadium.xcodeproj/project.pbxproj
+++ b/lib/Vanadium.xcodeproj/project.pbxproj
@@ -7,6 +7,12 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		93B980D31CAB9B6100CE42E0 /* Principal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93B980D21CAB9B6100CE42E0 /* Principal.swift */; };
+		93B980DC1CAB9D3D00CE42E0 /* Syncbase.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B980DB1CAB9D3D00CE42E0 /* Syncbase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		93B980E31CAB9D3D00CE42E0 /* Syncbase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93B980D91CAB9D3D00CE42E0 /* Syncbase.framework */; };
+		93B980E81CAB9D3D00CE42E0 /* SyncbaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93B980E71CAB9D3D00CE42E0 /* SyncbaseTests.swift */; };
+		93B980F31CAB9D6E00CE42E0 /* Security.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93B980F21CAB9D6E00CE42E0 /* Security.swift */; };
+		93B980F51CAB9D9000CE42E0 /* Syncbase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93B980F41CAB9D9000CE42E0 /* Syncbase.swift */; };
 		93BC21591C9E199F0074C612 /* VanadiumCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 93BC21581C9E199F0074C612 /* VanadiumCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		93BC21601C9E199F0074C612 /* VanadiumCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93BC21551C9E199F0074C612 /* VanadiumCore.framework */; };
 		93BC21F21C9E1B540074C612 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93BC21711C9E1B540074C612 /* Errors.swift */; };
@@ -32,6 +38,76 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
+		93B980E41CAB9D3D00CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93BC214C1C9E199F0074C612 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 93B980D81CAB9D3D00CE42E0;
+			remoteInfo = Syncbase;
+		};
+		93B980F01CAB9D5800CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93BC214C1C9E199F0074C612 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 93BC21541C9E199F0074C612;
+			remoteInfo = VanadiumCore;
+		};
+		93B981011CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = F8111E3319A95C8B0040E7D1;
+			remoteInfo = "Alamofire iOS";
+		};
+		93B981031CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = F8111E3E19A95C8B0040E7D1;
+			remoteInfo = "Alamofire iOS Tests";
+		};
+		93B981051CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4DD67C0B1A5C55C900ED2280;
+			remoteInfo = "Alamofire OSX";
+		};
+		93B981071CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = F829C6B21A7A94F100A2CD59;
+			remoteInfo = "Alamofire OSX Tests";
+		};
+		93B981091CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4CF626EF1BA7CB3E0011A099;
+			remoteInfo = "Alamofire tvOS";
+		};
+		93B9810B1CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = 4CF626F81BA7CB3E0011A099;
+			remoteInfo = "Alamofire tvOS Tests";
+		};
+		93B9810D1CAC57B400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = E4202FE01B667AA100C997FB;
+			remoteInfo = "Alamofire watchOS";
+		};
+		93B9810F1CAC57F400CE42E0 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+			proxyType = 1;
+			remoteGlobalIDString = F8111E3219A95C8B0040E7D1;
+			remoteInfo = "Alamofire iOS";
+		};
 		93BC21611C9E199F0074C612 /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
 			containerPortal = 93BC214C1C9E199F0074C612 /* Project object */;
@@ -42,6 +118,16 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		93B980D21CAB9B6100CE42E0 /* Principal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Principal.swift; path = security/Principal.swift; sourceTree = "<group>"; };
+		93B980D91CAB9D3D00CE42E0 /* Syncbase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Syncbase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		93B980DB1CAB9D3D00CE42E0 /* Syncbase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Syncbase.h; sourceTree = "<group>"; };
+		93B980DD1CAB9D3D00CE42E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		93B980E21CAB9D3D00CE42E0 /* SyncbaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SyncbaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		93B980E71CAB9D3D00CE42E0 /* SyncbaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncbaseTests.swift; sourceTree = "<group>"; };
+		93B980E91CAB9D3D00CE42E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		93B980F21CAB9D6E00CE42E0 /* Security.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Security.swift; sourceTree = "<group>"; };
+		93B980F41CAB9D9000CE42E0 /* Syncbase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Syncbase.swift; sourceTree = "<group>"; };
+		93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Alamofire.xcodeproj; path = "../../../third_party/swift/Alamofire-3.3.0/Alamofire.xcodeproj"; sourceTree = "<group>"; };
 		93BC21551C9E199F0074C612 /* VanadiumCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = VanadiumCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		93BC21581C9E199F0074C612 /* VanadiumCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VanadiumCore.h; sourceTree = "<group>"; };
 		93BC215A1C9E199F0074C612 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -70,6 +156,21 @@
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+		93B980D51CAB9D3D00CE42E0 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		93B980DF1CAB9D3D00CE42E0 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				93B980E31CAB9D3D00CE42E0 /* Syncbase.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		93BC21511C9E199F0074C612 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
@@ -90,12 +191,57 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		93B980D11CAB9B3E00CE42E0 /* security */ = {
+			isa = PBXGroup;
+			children = (
+				93B980D21CAB9B6100CE42E0 /* Principal.swift */,
+			);
+			name = security;
+			sourceTree = "<group>";
+		};
+		93B980DA1CAB9D3D00CE42E0 /* Syncbase */ = {
+			isa = PBXGroup;
+			children = (
+				93B980DB1CAB9D3D00CE42E0 /* Syncbase.h */,
+				93B980DD1CAB9D3D00CE42E0 /* Info.plist */,
+				93B980F21CAB9D6E00CE42E0 /* Security.swift */,
+				93B980F41CAB9D9000CE42E0 /* Syncbase.swift */,
+			);
+			path = Syncbase;
+			sourceTree = "<group>";
+		};
+		93B980E61CAB9D3D00CE42E0 /* SyncbaseTests */ = {
+			isa = PBXGroup;
+			children = (
+				93B980E71CAB9D3D00CE42E0 /* SyncbaseTests.swift */,
+				93B980E91CAB9D3D00CE42E0 /* Info.plist */,
+			);
+			path = SyncbaseTests;
+			sourceTree = "<group>";
+		};
+		93B980F81CAC57B400CE42E0 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				93B981021CAC57B400CE42E0 /* Alamofire.framework */,
+				93B981041CAC57B400CE42E0 /* Alamofire iOS Tests.xctest */,
+				93B981061CAC57B400CE42E0 /* Alamofire.framework */,
+				93B981081CAC57B400CE42E0 /* Alamofire OSX Tests.xctest */,
+				93B9810A1CAC57B400CE42E0 /* Alamofire.framework */,
+				93B9810C1CAC57B400CE42E0 /* Alamofire tvOS Tests.xctest */,
+				93B9810E1CAC57B400CE42E0 /* Alamofire.framework */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
 		93BC214B1C9E199F0074C612 = {
 			isa = PBXGroup;
 			children = (
 				93BC21571C9E199F0074C612 /* VanadiumCore */,
 				93BC21631C9E199F0074C612 /* VanadiumCoreTests */,
+				93B980DA1CAB9D3D00CE42E0 /* Syncbase */,
+				93B980E61CAB9D3D00CE42E0 /* SyncbaseTests */,
 				93BC21561C9E199F0074C612 /* Products */,
+				93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */,
 			);
 			sourceTree = "<group>";
 		};
@@ -104,6 +250,8 @@
 			children = (
 				93BC21551C9E199F0074C612 /* VanadiumCore.framework */,
 				93BC215F1C9E199F0074C612 /* VanadiumCoreTests.xctest */,
+				93B980D91CAB9D3D00CE42E0 /* Syncbase.framework */,
+				93B980E21CAB9D3D00CE42E0 /* SyncbaseTests.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -117,6 +265,7 @@
 				93BC21741C9E1B540074C612 /* context */,
 				93BC21761C9E1B540074C612 /* rpc */,
 				93BC21781C9E1B540074C612 /* rt */,
+				93B980D11CAB9B3E00CE42E0 /* security */,
 				93BC217A1C9E1B540074C612 /* util */,
 				93BC21821C9E1B540074C612 /* vdl */,
 				93BC21861C9E1B540074C612 /* x */,
@@ -212,6 +361,14 @@
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
+		93B980D61CAB9D3D00CE42E0 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				93B980DC1CAB9D3D00CE42E0 /* Syncbase.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		93BC21521C9E199F0074C612 /* Headers */ = {
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
@@ -225,6 +382,44 @@
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXNativeTarget section */
+		93B980D81CAB9D3D00CE42E0 /* Syncbase */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 93B980EA1CAB9D3D00CE42E0 /* Build configuration list for PBXNativeTarget "Syncbase" */;
+			buildPhases = (
+				93B980D41CAB9D3D00CE42E0 /* Sources */,
+				93B980D51CAB9D3D00CE42E0 /* Frameworks */,
+				93B980D61CAB9D3D00CE42E0 /* Headers */,
+				93B980D71CAB9D3D00CE42E0 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				93B981101CAC57F400CE42E0 /* PBXTargetDependency */,
+				93B980F11CAB9D5800CE42E0 /* PBXTargetDependency */,
+			);
+			name = Syncbase;
+			productName = Syncbase;
+			productReference = 93B980D91CAB9D3D00CE42E0 /* Syncbase.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+		93B980E11CAB9D3D00CE42E0 /* SyncbaseTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 93B980ED1CAB9D3D00CE42E0 /* Build configuration list for PBXNativeTarget "SyncbaseTests" */;
+			buildPhases = (
+				93B980DE1CAB9D3D00CE42E0 /* Sources */,
+				93B980DF1CAB9D3D00CE42E0 /* Frameworks */,
+				93B980E01CAB9D3D00CE42E0 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				93B980E51CAB9D3D00CE42E0 /* PBXTargetDependency */,
+			);
+			name = SyncbaseTests;
+			productName = SyncbaseTests;
+			productReference = 93B980E21CAB9D3D00CE42E0 /* SyncbaseTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
 		93BC21541C9E199F0074C612 /* VanadiumCore */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 93BC21691C9E199F0074C612 /* Build configuration list for PBXNativeTarget "VanadiumCore" */;
@@ -268,10 +463,16 @@
 		93BC214C1C9E199F0074C612 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastSwiftUpdateCheck = 0720;
+				LastSwiftUpdateCheck = 0730;
 				LastUpgradeCheck = 0720;
 				ORGANIZATIONNAME = "Google, Inc.";
 				TargetAttributes = {
+					93B980D81CAB9D3D00CE42E0 = {
+						CreatedOnToolsVersion = 7.3;
+					};
+					93B980E11CAB9D3D00CE42E0 = {
+						CreatedOnToolsVersion = 7.3;
+					};
 					93BC21541C9E199F0074C612 = {
 						CreatedOnToolsVersion = 7.2.1;
 					};
@@ -290,15 +491,89 @@
 			mainGroup = 93BC214B1C9E199F0074C612;
 			productRefGroup = 93BC21561C9E199F0074C612 /* Products */;
 			projectDirPath = "";
+			projectReferences = (
+				{
+					ProductGroup = 93B980F81CAC57B400CE42E0 /* Products */;
+					ProjectRef = 93B980F71CAC57B400CE42E0 /* Alamofire.xcodeproj */;
+				},
+			);
 			projectRoot = "";
 			targets = (
 				93BC21541C9E199F0074C612 /* VanadiumCore */,
 				93BC215E1C9E199F0074C612 /* VanadiumCoreTests */,
+				93B980D81CAB9D3D00CE42E0 /* Syncbase */,
+				93B980E11CAB9D3D00CE42E0 /* SyncbaseTests */,
 			);
 		};
 /* End PBXProject section */
 
+/* Begin PBXReferenceProxy section */
+		93B981021CAC57B400CE42E0 /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 93B981011CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		93B981041CAC57B400CE42E0 /* Alamofire iOS Tests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "Alamofire iOS Tests.xctest";
+			remoteRef = 93B981031CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		93B981061CAC57B400CE42E0 /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 93B981051CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		93B981081CAC57B400CE42E0 /* Alamofire OSX Tests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "Alamofire OSX Tests.xctest";
+			remoteRef = 93B981071CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		93B9810A1CAC57B400CE42E0 /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 93B981091CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		93B9810C1CAC57B400CE42E0 /* Alamofire tvOS Tests.xctest */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.cfbundle;
+			path = "Alamofire tvOS Tests.xctest";
+			remoteRef = 93B9810B1CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		93B9810E1CAC57B400CE42E0 /* Alamofire.framework */ = {
+			isa = PBXReferenceProxy;
+			fileType = wrapper.framework;
+			path = Alamofire.framework;
+			remoteRef = 93B9810D1CAC57B400CE42E0 /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+/* End PBXReferenceProxy section */
+
 /* Begin PBXResourcesBuildPhase section */
+		93B980D71CAB9D3D00CE42E0 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		93B980E01CAB9D3D00CE42E0 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		93BC21531C9E199F0074C612 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -333,6 +608,23 @@
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+		93B980D41CAB9D3D00CE42E0 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				93B980F31CAB9D6E00CE42E0 /* Security.swift in Sources */,
+				93B980F51CAB9D9000CE42E0 /* Syncbase.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		93B980DE1CAB9D3D00CE42E0 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				93B980E81CAB9D3D00CE42E0 /* SyncbaseTests.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		93BC21501C9E199F0074C612 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -346,6 +638,7 @@
 				93BC21F81C9E1B540074C612 /* Dates.swift in Sources */,
 				93BC21F71C9E1B540074C612 /* Runtime.swift in Sources */,
 				93BC22011C9E1B540074C612 /* VdlUtil.swift in Sources */,
+				93B980D31CAB9B6100CE42E0 /* Principal.swift in Sources */,
 				93BC21FD1C9E1B540074C612 /* Threads.swift in Sources */,
 				93BC21F61C9E1B540074C612 /* RPC.swift in Sources */,
 				93BC21FB1C9E1B540074C612 /* Promise.swift in Sources */,
@@ -366,6 +659,21 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
+		93B980E51CAB9D3D00CE42E0 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 93B980D81CAB9D3D00CE42E0 /* Syncbase */;
+			targetProxy = 93B980E41CAB9D3D00CE42E0 /* PBXContainerItemProxy */;
+		};
+		93B980F11CAB9D5800CE42E0 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 93BC21541C9E199F0074C612 /* VanadiumCore */;
+			targetProxy = 93B980F01CAB9D5800CE42E0 /* PBXContainerItemProxy */;
+		};
+		93B981101CAC57F400CE42E0 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			name = "Alamofire iOS";
+			targetProxy = 93B9810F1CAC57F400CE42E0 /* PBXContainerItemProxy */;
+		};
 		93BC21621C9E199F0074C612 /* PBXTargetDependency */ = {
 			isa = PBXTargetDependency;
 			target = 93BC21541C9E199F0074C612 /* VanadiumCore */;
@@ -374,6 +682,67 @@
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
+		93B980EB1CAB9D3D00CE42E0 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ENABLE_MODULES = YES;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Syncbase/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.v.Syncbase;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SKIP_INSTALL = YES;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+			};
+			name = Debug;
+		};
+		93B980EC1CAB9D3D00CE42E0 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ENABLE_MODULES = YES;
+				DEFINES_MODULE = YES;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				DYLIB_INSTALL_NAME_BASE = "@rpath";
+				INFOPLIST_FILE = Syncbase/Info.plist;
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.v.Syncbase;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SKIP_INSTALL = YES;
+			};
+			name = Release;
+		};
+		93B980EE1CAB9D3D00CE42E0 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				INFOPLIST_FILE = SyncbaseTests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.v.SyncbaseTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		93B980EF1CAB9D3D00CE42E0 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_ANALYZER_NONNULL = YES;
+				INFOPLIST_FILE = SyncbaseTests/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_BUNDLE_IDENTIFIER = io.v.SyncbaseTests;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
 		93BC21671C9E199F0074C612 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
@@ -398,6 +767,7 @@
 				COPY_PHASE_STRIP = NO;
 				CURRENT_PROJECT_VERSION = 1;
 				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_BITCODE = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -449,6 +819,7 @@
 				COPY_PHASE_STRIP = NO;
 				CURRENT_PROJECT_VERSION = 1;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_BITCODE = NO;
 				ENABLE_NS_ASSERTIONS = NO;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -476,7 +847,6 @@
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
-				ENABLE_BITCODE = NO;
 				INFOPLIST_FILE = VanadiumCore/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -499,7 +869,6 @@
 				DYLIB_COMPATIBILITY_VERSION = 1;
 				DYLIB_CURRENT_VERSION = 1;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
-				ENABLE_BITCODE = NO;
 				INFOPLIST_FILE = VanadiumCore/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -541,6 +910,24 @@
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+		93B980EA1CAB9D3D00CE42E0 /* Build configuration list for PBXNativeTarget "Syncbase" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				93B980EB1CAB9D3D00CE42E0 /* Debug */,
+				93B980EC1CAB9D3D00CE42E0 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		93B980ED1CAB9D3D00CE42E0 /* Build configuration list for PBXNativeTarget "SyncbaseTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				93B980EE1CAB9D3D00CE42E0 /* Debug */,
+				93B980EF1CAB9D3D00CE42E0 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		93BC214F1C9E199F0074C612 /* Build configuration list for PBXProject "Vanadium" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
diff --git a/lib/VanadiumCore/bridge/Errors.swift b/lib/VanadiumCore/bridge/Errors.swift
index 8248928..d7cf957 100644
--- a/lib/VanadiumCore/bridge/Errors.swift
+++ b/lib/VanadiumCore/bridge/Errors.swift
@@ -14,7 +14,7 @@
   public let stacktrace:String?
 }
 
-/// Equality for VError is determined SOLEY by comparing identifiers. Identifiers are required
+/// Equality for VError is determined SOLELY by comparing identifiers. Identifiers are required
 /// to be unique in VDL. Equality is defined this way as the primary use case is to compare
 /// runtime VErrors against VDL-generated static errors. For example:
 ///
@@ -32,7 +32,7 @@
 /// SwiftVError is the C struct that the go bridge uses to transfer an error to Swift.
 internal extension SwiftVError {
   internal func isEmpty() -> Bool { return identity == nil || identity.memory == 0 }
- 
+
   /// Helper to run a go-bridge method that might fill out this struct on error. In that scenario
   /// we translate that into a Swift-based error and throw it.
   /// VError's static _delegate slot is the actual function that throws a given converted VError
@@ -51,7 +51,7 @@
     return ret
   }
 
-  /// Convert the C Struct into a Swift-based VError struct. 
+  /// Convert the C Struct into a Swift-based VError struct.
   /// Go allocates the underlying strings, and swift must take control of them and free them when done
   internal func toSwift() -> VError {
     return VError(
diff --git a/lib/VanadiumCore/bridge/Refs.swift b/lib/VanadiumCore/bridge/Refs.swift
index 87bc44d..20e4d3a 100644
--- a/lib/VanadiumCore/bridge/Refs.swift
+++ b/lib/VanadiumCore/bridge/Refs.swift
@@ -15,20 +15,20 @@
   internal init(timeout:NSTimeInterval?) {
     timeoutDelay = timeout
   }
-  
+
   internal func newPromise() -> (AsyncId, Promise<ResolveType>) {
     let p = Promise<ResolveType>()
     if let timeout = timeoutDelay { p.rejectAfterDelay(delay: timeout) }
     let asyncId = OSAtomicIncrement32(&lastId)
     lock { self.promises[asyncId] = p }
     p.always { _ in
-      // Guaruntee we delete the ref on resolution 
+      // Guarantee we delete the ref on resolution
       // (can happen on delayed timeout that it wouldn't get cleaned)
       self.lock { self.promises[asyncId] = nil }
     }
     return (asyncId, p)
   }
-  
+
   internal func getAndDeleteRef(asyncId:AsyncId) -> Promise<ResolveType>? {
     guard let p = promises[asyncId] else { return nil }
     lock { self.promises[asyncId] = nil }
diff --git a/lib/VanadiumCore/bridge/Types.swift b/lib/VanadiumCore/bridge/Types.swift
index e912856..b553bb5 100644
--- a/lib/VanadiumCore/bridge/Types.swift
+++ b/lib/VanadiumCore/bridge/Types.swift
@@ -43,35 +43,35 @@
 //      block(empty)
 //      return
 //    }
-//    
+//
 //    // We use the NSString bridge as its an order of magnitude faster than using nulTerminatedUtf8,
 //    // the UTF8 views, or withCString as of Swift 2.1 (11/17/15)
 //    let utf8 = (str as NSString).UTF8String
 //    let goStr = GoString(p: UnsafeMutablePointer<Int8>(utf8), n: GoInt(strlen(utf8)))
 //    block(goStr)
 //  }
-//  
+//
 //  /// An empty (nil) string
 //  static let empty = GoString(p: nil, n: 0)
 //}
 
 extension SwiftByteArrayArray : CollectionType, CustomDebugStringConvertible {
   public typealias Index = Int
-  
+
   public var startIndex: Int {
     return 0
   }
-  
+
   public var endIndex: Int {
     return count()
   }
-  
+
   public subscript(i: Int) -> SwiftByteArray {
     return data[i]
   }
-  
+
   public func count() -> Int { return Int(length) }
-  
+
   public func dealloc() {
     for i in 0..<length {
       let byteArray = data[Int(i)]
@@ -79,7 +79,7 @@
     }
     data.dealloc(count())
   }
-  
+
   public var debugDescription: String {
     get {
       var totalSize = 0
@@ -93,15 +93,19 @@
 
 extension SwiftByteArray : CustomDebugStringConvertible {
   public func count() -> Int { return Int(length) }
-  
+
   public func dealloc() {
     data.dealloc(count())
   }
-  
+
   public func toNSDataNoCopyNoFree() -> NSData {
     return NSData(bytesNoCopy: data, length: count(), freeWhenDone: false)
   }
-  
+
+  public func toNSDataNoCopyFreeWhenDone() -> NSData {
+    return NSData(bytesNoCopy: data, length: count(), freeWhenDone: true)
+  }
+
   public var debugDescription: String {
     get {
       let utf8 = NSString(
diff --git a/lib/VanadiumCore/context/Context.swift b/lib/VanadiumCore/context/Context.swift
index ce011a6..525cc86 100644
--- a/lib/VanadiumCore/context/Context.swift
+++ b/lib/VanadiumCore/context/Context.swift
@@ -14,22 +14,22 @@
   private var _isCancellable:Bool = false
   private var dirty:ContextFeatures = []
   public var userInfo:[String: Any] = [:]
-  
+
   internal init(handle:ContextHandle) {
     self.handle = handle
   }
-  
+
   internal init(handle:ContextHandle, existingDeadline:NSDate?, isCancellable:Bool) {
     self.handle = handle
     self.deadline = existingDeadline
     self._isCancellable = isCancellable
   }
-  
+
   public mutating func client() throws -> Client {
     try updateHandleIfNeeded()
     return Client(defaultContext: self)
   }
-  
+
   public var deadline:NSDate? {
     didSet {
       guard oldValue != deadline else { return }
@@ -46,9 +46,9 @@
       dirty.insert(ContextFeatures.Deadline)
     }
   }
-  
+
   public var isCancelled:Bool { return _isCancelled }
-  
+
   public var isCancellable:Bool {
     get {
       return !_isCancelled && (_isCancellable || dirty.contains(ContextFeatures.Cancellable))
@@ -67,7 +67,7 @@
       dirty.insert(ContextFeatures.Cancellable)
     }
   }
-  
+
   /// Cancels all associated RPC with this context and renders it unusable. Call newContext afterwards
   /// to get a similar context that is workable.
   ///
@@ -94,21 +94,21 @@
     })
     return p
   }
-  
+
   internal mutating func updateHandleIfNeeded() throws {
     if (_isCancelled) {
       throw ContextError.ContextIsAlreadyCancelled
     }
-    
+
     if dirty.contains(ContextFeatures.Deadline) {
       try updateHandleForDeadline()
     }
-    
+
     if dirty.contains(ContextFeatures.Cancellable) {
       try updateHandleForCancellable()
     }
   }
-  
+
   private mutating func updateHandleForDeadline() throws {
     guard let deadline = deadline else {
       fatalError("Deadline was assumed to not be nil here, yet was marked as dirty")
@@ -121,7 +121,7 @@
     dirty.remove(ContextFeatures.Deadline)
     handle = ContextHandle(goHandle)
   }
-  
+
   private mutating func updateHandleForCancellable() throws {
     let goHandle = try SwiftVError.catchAndThrowError { errPtr in
       return swift_io_v_v23_context_VContext_nativeWithCancel(
@@ -131,7 +131,7 @@
     dirty.remove(ContextFeatures.Cancellable)
     handle = ContextHandle(goHandle)
   }
-  
+
   internal mutating func run<T>(@autoclosure block: () throws ->T) throws -> T {
     guard !_isCancelled else { throw ContextError.ContextIsAlreadyCancelled }
     try updateHandleIfNeeded()
@@ -141,7 +141,7 @@
 
 public class ContextHandle: CustomStringConvertible, CustomDebugStringConvertible {
   internal let goHandle:GoContextHandle
-  
+
   internal init(_ goHandle:GoContextHandle) {
     self.goHandle = goHandle
   }
@@ -151,7 +151,7 @@
       swift_io_v_v23_context_VContext_nativeFinalize(goHandle)
     }
   }
-  
+
   public var description: String { return "[ContextHandle \(goHandle)]" }
   public var debugDescription: String { return "[ContextHandle handle=\(goHandle)]" }
 }
diff --git a/lib/VanadiumCore/rpc/RPC.swift b/lib/VanadiumCore/rpc/RPC.swift
index 7488056..35411c9 100644
--- a/lib/VanadiumCore/rpc/RPC.swift
+++ b/lib/VanadiumCore/rpc/RPC.swift
@@ -15,15 +15,15 @@
 
 public struct Client {
   internal let defaultContext:Context
-  
+
   internal init(defaultContext:Context) {
     self.defaultContext = defaultContext
   }
-  
+
   internal func ctxHandle(ctx:Context?) -> ContextHandle {
     return (ctx ?? defaultContext).handle
   }
-  
+
   public func startCall(ctx:Context?=nil, name:String, method:String, args:[AnyObject]?=nil, returnArgsLength:Int,
                         skipServerAuth:Bool=false) -> Promise<ClientCall> {
     let vomArgs = SwiftByteArrayArray(length: 0, data: nil)
@@ -43,9 +43,9 @@
         ctxHandle: self.ctxHandle(ctx), callHandle: handle, returnArgsLength: returnArgsLength)
     }
   }
- 
+
   private static let outstandingHandles = GoPromises<GoClientCallHandle>(timeout: nil)
-  
+
   public func call(ctx:Context?=nil, name:String, method:String, args:[AnyObject]?=nil, returnArgsLength:Int,
                    skipServerAuth:Bool=false) -> Promise<[AnyObject]?> {
     return startCall(
@@ -71,7 +71,7 @@
       }
     }
   }
-  
+
   internal static func callDidFail(asyncId:AsyncCallbackIdentifier, err:SwiftVError) {
     let verr = err.toSwift()
     if let p = Client.outstandingHandles.getAndDeleteRef(asyncId) {
@@ -84,7 +84,7 @@
       }
     }
   }
-  
+
   public func close(ctx:Context?=nil) {
     swift_io_v_impl_google_rpc_ClientImpl_nativeClose(ctxHandle(ctx).goHandle)
   }
@@ -98,7 +98,7 @@
   internal let ctxHandle:ContextHandle
   internal let callHandle:GoClientCallHandle
   internal let returnArgsLength:Int
- 
+
   internal init(ctxHandle:ContextHandle, callHandle:GoClientCallHandle, returnArgsLength:Int) throws {
     self.ctxHandle = ctxHandle
     self.callHandle = callHandle
@@ -107,19 +107,19 @@
       throw ClientCallErrors.NilHandlerOnInit
     }
   }
-  
+
   deinit {
     if callHandle != 0 {
       swift_io_v_impl_google_rpc_ClientCallImpl_nativeFinalize(callHandle)
     }
   }
-  
+
   public func closeSend() throws {
     try SwiftVError.catchAndThrowError { errPtr in
       swift_io_v_impl_google_rpc_ClientCallImpl_nativeCloseSend(ctxHandle.goHandle, callHandle, errPtr)
     }
   }
- 
+
   private static let outstandingFinishes = GoPromises<[AnyObject]?>(timeout: nil)
   public func finish() throws -> Promise<[AnyObject]?> {
     let (asyncId, p) = ClientCall.outstandingFinishes.newPromise()
@@ -137,12 +137,12 @@
       byteArrayArray.dealloc()
       return
     }
-   
+
     // VOM decode in background to let Go get free'd up and to not block main
     RunInBackground {
       // Deallocate associated bytes malloc'd in Go
       defer { byteArrayArray.dealloc() }
-      
+
       do {
         // TODO Decode via VOM
 //        log.debug("Got back byteArrayArray \(byteArrayArray) and data \(byteArrayArray.data)")
@@ -155,7 +155,7 @@
         do { try p.reject(e) } catch {}
         return
       }
-      
+
       do {
         try p.resolve(nil)
       } catch let e {
@@ -163,7 +163,7 @@
       }
     }
   }
-  
+
   internal static func finishDidFail(asyncId:AsyncCallbackIdentifier, err:SwiftVError) {
     let verr = err.toSwift()
     if let p = ClientCall.outstandingFinishes.getAndDeleteRef(asyncId) {
@@ -176,7 +176,7 @@
       }
     }
   }
-  
+
 //  public func remoteBlessings() -> (blessings:[String], cryptoBlessings:[Blessings]) {
 //    fatalError("Unimplemented")
 //  }
diff --git a/lib/VanadiumCore/rt/Runtime.swift b/lib/VanadiumCore/rt/Runtime.swift
index 14622c6..c5653ca 100644
--- a/lib/VanadiumCore/rt/Runtime.swift
+++ b/lib/VanadiumCore/rt/Runtime.swift
@@ -32,33 +32,48 @@
       _instance = newValue
     }
   }
-  
+
   /// Private constructor for V23.
   private init(loggingOptions:VLoggingOptions) throws {
     // We must have all variables initialized before we can throw
     rootContext = Context(handle: ContextHandle(0))
-    try SwiftVError.catchAndThrowError { errPtr in
-      swift_io_v_v23_V_nativeInitGlobal(errPtr)
+
+    let appSupportUrl = NSURL(fileURLWithPath:
+      NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true)[0])
+    let v23Url = appSupportUrl.URLByAppendingPathComponent("Vanadium")
+    let credentialsPath = v23Url.path!
+    log.debug("Using credentials path \(credentialsPath)")
+    if !NSFileManager.defaultManager().fileExistsAtPath(credentialsPath) {
+      // Create it
+      let attrs = [NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication]
+      try NSFileManager.defaultManager().createDirectoryAtPath(
+        credentialsPath, withIntermediateDirectories: true, attributes: attrs)
     }
+    try SwiftVError.catchAndThrowError { errPtr in
+      swift_io_v_v23_V_nativeInitGlobal(credentialsPath.toGo(), errPtr)
+    }
+
     try loggingOptions.initGo()
     rootContext = Context(handle: ContextHandle(swift_io_v_impl_google_rt_VRuntimeImpl_nativeInit()))
   }
-  
+
   deinit {
     swift_io_v_impl_google_rt_VRuntimeImpl_nativeShutdown(rootContext.handle.goHandle)
   }
-  
+
   /// You must call configure before using Vanadium or grabbing an instance.
   /// This is where you pass any logging options... (TBD)
   ///
   /// **Warning:** You may only call this once. It will otherwise crash with a fatalError.
   ///
-  /// :param: loggingOptions Logging options used by the Vandadium internals. 
+  /// :param: loggingOptions Logging options used by the Vandadium internals.
   ///         See documentation on VLoggingOptions for more information
   public class func configure(loggingOptions:VLoggingOptions?=nil) throws {
-    instance = try V23(loggingOptions: loggingOptions ?? VLoggingOptions())
+    if _instance == nil {
+      instance = try V23(loggingOptions: loggingOptions ?? VLoggingOptions())
+    }
   }
-  
+
   public var context: Context {
     get {
       return rootContext
diff --git a/lib/VanadiumCore/security/Principal.swift b/lib/VanadiumCore/security/Principal.swift
new file mode 100644
index 0000000..f42d3af
--- /dev/null
+++ b/lib/VanadiumCore/security/Principal.swift
@@ -0,0 +1,49 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import Foundation
+
+/// Principal houses the basic tools for blessing the principal, which is to say it
+/// contains the functions needed for authentication between devices/users.
+public enum Principal {
+  /// Sets the blessing for the principal. This blessing must be VOM encoded, and is typically
+  /// provided by a Vanadium-service over HTTP (for example exchanging an oauth token for a V23
+  /// blessing).
+  public static func setBlessings(vomEncodedBlessings:NSData) throws {
+    let ctx = V23.instance.context
+    // We can safely force this case because we know that CGO won't actually modify any of the
+    // NSData's bytes.
+    let cgoData = unsafeBitCast(vomEncodedBlessings.bytes, UnsafeMutablePointer<Void>.self)
+    let data = SwiftByteArray(length: UInt64(vomEncodedBlessings.length), data: cgoData)
+    try SwiftVError.catchAndThrowError { errPtr in
+      swift_io_v_v23_security_simple_nativeSetBlessings(ctx.handle.goHandle, data, errPtr)
+    }
+  }
+
+  /// Returns a string that encapsulates the current blessing of the principal. It will look
+  /// something like dev.v.io:o:6183738471-jsl8jlsaj.apps.googleusercontent.com:frank@gmail.com
+  public static func blessingsDebugString() throws -> String {
+    let ctx = V23.instance.context
+    let cstr = swift_io_v_v23_security_simple_nativeBlessingsDebugString(ctx.handle.goHandle)
+    let str = String.fromCStringNoCopy(cstr, freeWhenDone: true)
+    if str == nil {
+      throw StringErrors.InvalidString
+    }
+    return str!
+  }
+
+  /// Base64 DER-encoded representation of the auto-generated public-key using Golang's URLEncoding,
+  /// which is not compatible with NSData's base64 encoder/decoder.
+  public static func publicKey() throws -> String {
+    let str:String? = try SwiftVError.catchAndThrowError { errPtr in
+      let ctx = V23.instance.context
+      let cstr = swift_io_v_v23_security_simple_nativePublicKey(ctx.handle.goHandle, errPtr)
+      return String.fromCStringNoCopy(cstr, freeWhenDone: true)
+    }
+    if str == nil {
+      throw StringErrors.InvalidString
+    }
+    return str!
+  }
+}
diff --git a/lib/VanadiumCore/util/Logging.swift b/lib/VanadiumCore/util/Logging.swift
index 1644584..50c707a 100644
--- a/lib/VanadiumCore/util/Logging.swift
+++ b/lib/VanadiumCore/util/Logging.swift
@@ -4,29 +4,29 @@
 
 import Foundation
 
-internal let log = VLogger()
+public let log = VLogger()
 
 public struct VLogger {
-  internal func debug(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
+  public func debug(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
     log("DEBUG", str: closure(), functionName: functionName, fileName: fileName, lineNumber: lineNumber)
   }
-  
-  internal func info(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
+
+  public func info(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
     log("INFO", str: closure(), functionName: functionName, fileName: fileName, lineNumber: lineNumber)
   }
-  
-  internal func warning(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
+
+  public func warning(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
     log("WARN", str: closure(), functionName: functionName, fileName: fileName, lineNumber: lineNumber)
   }
-  
-  internal func error(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
+
+  public func error(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
     log("ERROR", str: closure(), functionName: functionName, fileName: fileName, lineNumber: lineNumber)
   }
-  
-  internal func fatal(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
+
+  public func fatal(@autoclosure closure: () -> String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
     log("FATAL", str: closure(), functionName: functionName, fileName: fileName, lineNumber: lineNumber)
   }
-  
+
   private func log(level:String, str:String, functionName: String = #function, fileName: String = #file, lineNumber: Int = #line) {
     if let threadName = NSThread.currentThread().name where threadName != "" {
       print("[", level, "] ", (fileName as NSString).lastPathComponent, ":", lineNumber, " (", threadName, ") ", str, separator: "")
@@ -46,22 +46,22 @@
 public struct VLoggingOptions {
   /// Enable V-leveled logging at the specified level.
   let level: VLogLevel
-  
+
   /// The syntax of the argument is a comma-separated list of pattern=N,
   /// where pattern is a literal file name (minus the ".go" suffix) or
   /// "glob" pattern and N is a V level. For instance, gopher*=3
   /// sets the V level to 3 in all Go files whose names begin "gopher".
   let moduleSpec: String?
-  
+
   // We only log to disk on OS X
   #if os(OSX)
   /// If true, logs are written to standard error instead of to files
   let logToStderrOnly: Bool
-  
+
   /// Log files will be wirtten to this directory instead of the default temp dir
   let logDir: String?
   #endif
-  
+
   #if os(OSX)
   public init(level:VLogLevel=VLogLevel.Info,
       moduleSpec:String?=nil,
@@ -81,7 +81,7 @@
     self.moduleSpec = moduleSpec
   }
   #endif
- 
+
   /// Call the init logging function in go -- INTERNAL ONLY
   internal func initGo() throws {
     #if os(OSX)
diff --git a/lib/VanadiumCore/util/Promise.swift b/lib/VanadiumCore/util/Promise.swift
index dbf0505..89c0a06 100644
--- a/lib/VanadiumCore/util/Promise.swift
+++ b/lib/VanadiumCore/util/Promise.swift
@@ -22,15 +22,15 @@
   private var rejectCallbacks:[(dispatch_queue_t?, ErrorType?->())]? = nil
   private var alwaysCallbacks:[(dispatch_queue_t?, PromiseResolution<ResolveType>->())]? = nil
   private let resolutionSemaphore = dispatch_semaphore_create(0)
-  
+
   internal var status: PromiseResolution<ResolveType> = PromiseResolution.Pending {
     didSet {
       updatedStatus()
     }
   }
-  
+
   public init() { }
-  
+
   public convenience init(resolved obj: ResolveType) {
     self.init()
     status = PromiseResolution<ResolveType>.Resolved(obj: obj)
@@ -40,7 +40,7 @@
     self.init()
     status = PromiseResolution<ResolveType>.Rejected(err: err)
   }
-  
+
   // Resolve/reject
   public func resolve(obj:ResolveType) throws {
     objc_sync_enter(self)
@@ -51,7 +51,7 @@
     case .Pending: status = PromiseResolution.Resolved(obj: obj)
     }
   }
-  
+
   public func reject(err:ErrorType?) throws {
     objc_sync_enter(self)
     defer { objc_sync_exit(self) }
@@ -76,10 +76,10 @@
       }
       resolveCallbacks!.append((queue, callback))
     }
-                          
+
     return self
   }
-  
+
   public func onReject(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
                        _ callback:ErrorType?->()) -> Promise<ResolveType> {
     objc_sync_enter(self)
@@ -95,7 +95,7 @@
     }
     return self
   }
-  
+
   public func always(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
                      _ callback:PromiseResolution<ResolveType>->()) -> Promise<ResolveType> {
     objc_sync_enter(self)
@@ -111,7 +111,7 @@
     }
     return self
   }
-  
+
   public func await(timeout: NSTimeInterval?=nil) throws -> PromiseResolution<ResolveType> {
     switch (status) {
     case .Pending:
@@ -126,7 +126,7 @@
     }
     return status
   }
-  
+
   // Changing states
   internal func updatedStatus() {
     // Do reject/resolve callbacks, then always callbacks
@@ -148,7 +148,7 @@
         }
       }
     }
-    
+
     defer { dispatch_semaphore_signal(resolutionSemaphore) }
     guard let callbacks = alwaysCallbacks else { return }
     for (queue, callback) in callbacks {
@@ -161,17 +161,17 @@
 
 public class ResolvedPromise<ResolveType>: Promise<ResolveType> {
   var resolvedObj:ResolveType
-  
+
   override private init() {
     fatalError("Cannot init this way")
   }
-  
+
   public convenience init(_ resolved: ResolveType) {
     self.init(resolved: resolved)
     self.resolvedObj = resolved
     dispatch_semaphore_signal(resolutionSemaphore)
   }
-  
+
   override public func onResolve(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
     _ callback:ResolveType->()) -> Promise<ResolveType> {
       dispatch_maybe_async(queue, block: { callback(self.resolvedObj) })
@@ -183,7 +183,7 @@
       dispatch_maybe_async(queue, block: { callback(self.status) })
       return self
   }
-  
+
   override public func resolve(obj:ResolveType) throws {
     throw PromiseErrors<ResolveType>.AlreadyResolved(existingObj: resolvedObj)
   }
@@ -195,17 +195,17 @@
 
 public class RejectedPromise: Promise<Void> {
   var err:ErrorType?
-  
+
   override private init() {
     fatalError("Cannot init this way")
   }
-  
+
   public convenience init(_ error: ErrorType?) {
     self.init(rejected: error)
     self.err = error
     dispatch_semaphore_signal(resolutionSemaphore)
   }
-  
+
   override public func onReject(on queue: dispatch_queue_t?, _ callback: ErrorType? -> ()) -> Promise<Void> {
     dispatch_maybe_async(queue, block: { callback(self.err) })
     return self
@@ -216,7 +216,7 @@
     dispatch_maybe_async(queue, block: { callback(self.status) })
     return self
   }
-  
+
   override public func resolve(obj:Void) throws {
     throw PromiseErrors<Void>.AlreadyRejected(existingErr: self.err)
   }
@@ -251,12 +251,12 @@
     }
     return p
   }
- 
+
   /// Specialize then for when it returns another Promise to hook onto that automatically
   func then<T>(on queue: dispatch_queue_t?=dispatch_get_main_queue(),
                _ callback:ResolveType throws ->Promise<T>) -> Promise<T> {
     let p = Promise<T>()
-                
+
     onResolve(on: queue) { obj in
       do {
         let newPromise = try callback(obj)
@@ -274,13 +274,13 @@
         try! p.reject(e)
       }
     }
-                
+
     onReject(on: queue) { err in
       try! p.reject(err)
     }
     return p
   }
-  
+
   func thenInBackground<T>(callback:ResolveType throws ->T) -> Promise<T> {
     return then(on: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), callback)
   }
@@ -298,14 +298,14 @@
     default: return false
     }
   }
-  
+
   public func isResolved() -> Bool {
     switch (status) {
     case .Resolved: return true
     default: return false
     }
   }
-  
+
   public func isRejected() -> Bool {
     switch (status) {
     case .Rejected: return true
diff --git a/lib/VanadiumCore/util/Strings.swift b/lib/VanadiumCore/util/Strings.swift
index 31ac9fd..9a26a2e 100644
--- a/lib/VanadiumCore/util/Strings.swift
+++ b/lib/VanadiumCore/util/Strings.swift
@@ -1,10 +1,6 @@
-//
-//  Strings.swift
-//  v23
-//
-//  Created by Aaron Zinman on 12/1/15.
-//  Copyright © 2015 Google Inc. All rights reserved.
-//
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 import Foundation
 
@@ -13,4 +9,8 @@
     return String.init(bytesNoCopy: ptr, length: Int(strlen(ptr)),
       encoding: NSUTF8StringEncoding, freeWhenDone: true)
   }
+}
+
+public enum StringErrors : ErrorType {
+  case InvalidString
 }
\ No newline at end of file
diff --git a/lib/VanadiumCore/vdl/VdlTypes.swift b/lib/VanadiumCore/vdl/VdlTypes.swift
index ca17221..2bc214f 100644
--- a/lib/VanadiumCore/vdl/VdlTypes.swift
+++ b/lib/VanadiumCore/vdl/VdlTypes.swift
@@ -4,7 +4,7 @@
 
 import Foundation
 
-// Define protocols 
+// Define protocols
 
 public protocol VdlTypeProtocol {
   static var vdlTypeName: String { get }
@@ -147,7 +147,7 @@
   case Float32(name:SwiftString?)
   /// 64 bit IEEE 754 floating point
   case Float64(name:SwiftString?)
-  /// {realimag} each 32 bit IEEE 754 floating point
+  /// unicode string (encoded as UTF-8 in memory)
   case String(name:SwiftString?)
   /// one of a set of labels
   case Enum(name:SwiftString?, labels:[SwiftString]?)
diff --git a/lib/VanadiumCore/vdl/VdlUtil.swift b/lib/VanadiumCore/vdl/VdlUtil.swift
index 5c39850..bebb800 100644
--- a/lib/VanadiumCore/vdl/VdlUtil.swift
+++ b/lib/VanadiumCore/vdl/VdlUtil.swift
@@ -1,10 +1,6 @@
-//
-//  VdlUtil.swift
-//  v23
-//
-//  Created by zinman on 2/18/16.
-//  Copyright © 2016 Google Inc. All rights reserved.
-//
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 import Foundation
 
diff --git a/lib/VanadiumCoreTests/CoreTests.swift b/lib/VanadiumCoreTests/CoreTests.swift
index 7bdf51d..50b82c3 100644
--- a/lib/VanadiumCoreTests/CoreTests.swift
+++ b/lib/VanadiumCoreTests/CoreTests.swift
@@ -1,19 +1,15 @@
-//
-//  v23Tests.swift
-//  v23Tests
-//
-//  Created by Aaron Zinman on 11/12/15.
-//  Copyright © 2015 Google Inc. All rights reserved.
-//
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 import XCTest
 @testable import VanadiumCore
 
 class VanadiumCoreTests: XCTestCase {
-    func testInit() {
-      // Currently this fails because of environmental flags passed by the Unit Test framework
-      // that Vanadium ends up reading in and barfing on. Need to solve at some point.
-      try! V23.configure()
-      let instance = V23.instance
-    }
+  func testInit() {
+    // Currently this fails because of environmental flags passed by the Unit Test framework
+    // that Vanadium ends up reading in and barfing on. Need to solve at some point.
+    try! V23.configure()
+    let instance = V23.instance
+  }
 }
diff --git a/lib/VanadiumCoreTests/PromiseTests.swift b/lib/VanadiumCoreTests/PromiseTests.swift
index 9e78f72..ae132cd 100644
--- a/lib/VanadiumCoreTests/PromiseTests.swift
+++ b/lib/VanadiumCoreTests/PromiseTests.swift
@@ -1,10 +1,6 @@
-//
-//  PromiseTests.swift
-//  v23
-//
-//  Created by Aaron Zinman on 11/30/15.
-//  Copyright © 2015 Google Inc. All rights reserved.
-//
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 import XCTest
 import VanadiumCore