Define syncgroup.ID, the globally unique identifier of a syncgroup.
Currently it is implemented as a storage.ID.

Change-Id: Ic29e97b104685ee76d6175e52173d6918216631d
diff --git a/services/syncgroup/id.go b/services/syncgroup/id.go
new file mode 100644
index 0000000..898d871
--- /dev/null
+++ b/services/syncgroup/id.go
@@ -0,0 +1,29 @@
+package syncgroup
+
+import "veyron2/storage"
+
+// The current implementation of SyncGroupID assumes that an ID is a storage.ID.
+// ID is defined in syncgroup.vdl.
+
+// NewID returns a new ID.
+func NewID() ID {
+	return ID(storage.NewID())
+}
+
+// String returns id as a hex string.
+func (id ID) String() string {
+	return storage.ID(id).String()
+}
+
+// TODO(m3b): Add a string-to-ID function here.  Perhaps it should conform to fmt.Scanner,
+// to parallel String() conforming to fmt.Stringer.
+
+// IsValid returns whether id is not the zero id.
+func (id ID) IsValid() bool {
+	return storage.ID(id).IsValid()
+}
+
+// CompareIDs compares two IDs lexicographically.
+func CompareIDs(id1 ID, id2 ID) int {
+	return storage.CompareIDs(storage.ID(id1), storage.ID(id2))
+}
diff --git a/services/syncgroup/syncgroup.vdl b/services/syncgroup/syncgroup.vdl
index 7339201..0531567 100644
--- a/services/syncgroup/syncgroup.vdl
+++ b/services/syncgroup/syncgroup.vdl
@@ -19,6 +19,9 @@
 // import "veyron2/services/watch"  // Watch call is not yet implemented
 import "veyron2/storage"
 
+// An ID is a globally unique identifier for a SyncGroup.
+type ID storage.ID
+
 // A SyncGroupInfo is the conceptual state of a SyncGroup object.
 type SyncGroupInfo struct {
 	Name    string          // Global Veyron name of object.
@@ -28,7 +31,7 @@
 
 	// The SyncGroup's object ID, which is chosen by the creating SyncGroupServer
 	// and is globally unique.
-	SGOID storage.ID
+	SGOID ID
 
 	// A map from joiner names to the associated metaData for devices that
 	// have called Join() or Create() and not subsequently called Leave()
diff --git a/services/syncgroup/syncgroup.vdl.go b/services/syncgroup/syncgroup.vdl.go
index 4dc721f..e38974f 100644
--- a/services/syncgroup/syncgroup.vdl.go
+++ b/services/syncgroup/syncgroup.vdl.go
@@ -33,6 +33,9 @@
 	_gen_wiretype "veyron2/wiretype"
 )
 
+// An ID is a globally unique identifier for a SyncGroup.
+type ID storage.ID
+
 // A SyncGroupInfo is the conceptual state of a SyncGroup object.
 type SyncGroupInfo struct {
 	Name    string          // Global Veyron name of object.
@@ -41,7 +44,7 @@
 	ETag    string          // Version ID for concurrency control.
 	// The SyncGroup's object ID, which is chosen by the creating SyncGroupServer
 	// and is globally unique.
-	SGOID storage.ID
+	SGOID ID
 	// A map from joiner names to the associated metaData for devices that
 	// have called Join() or Create() and not subsequently called Leave()
 	// or had Eject() called on them.  The map returned by the calls below
@@ -439,14 +442,14 @@
 			{Name: "metaData", Type: 76},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "sgInfo", Type: 78},
-			{Name: "err", Type: 79},
+			{Name: "sgInfo", Type: 79},
+			{Name: "err", Type: 80},
 		},
 	}
 	result.Methods["Destroy"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 79},
+			{Name: "", Type: 80},
 		},
 	}
 	result.Methods["Eject"] = _gen_ipc.MethodSignature{
@@ -454,14 +457,14 @@
 			{Name: "name", Type: 75},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 79},
+			{Name: "", Type: 80},
 		},
 	}
 	result.Methods["Get"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "sgInfo", Type: 78},
-			{Name: "err", Type: 79},
+			{Name: "sgInfo", Type: 79},
+			{Name: "err", Type: 80},
 		},
 	}
 	result.Methods["Join"] = _gen_ipc.MethodSignature{
@@ -470,8 +473,8 @@
 			{Name: "metaData", Type: 76},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "sgInfo", Type: 78},
-			{Name: "err", Type: 79},
+			{Name: "sgInfo", Type: 79},
+			{Name: "err", Type: 80},
 		},
 	}
 	result.Methods["Leave"] = _gen_ipc.MethodSignature{
@@ -479,7 +482,7 @@
 			{Name: "name", Type: 75},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 79},
+			{Name: "", Type: 80},
 		},
 	}
 	result.Methods["SetConfig"] = _gen_ipc.MethodSignature{
@@ -488,7 +491,7 @@
 			{Name: "eTag", Type: 3},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 79},
+			{Name: "", Type: 80},
 		},
 	}
 
@@ -524,14 +527,14 @@
 				_gen_wiretype.FieldType{Type: 0x24, Name: "SyncPriority"},
 			},
 			"veyron/services/syncgroup.JoinerMetaData", []string(nil)},
-		_gen_wiretype.MapType{Key: 0x4b, Elem: 0x4c, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
+		_gen_wiretype.ArrayType{Elem: 0x49, Len: 0x10, Name: "veyron/services/syncgroup.ID", Tags: []string(nil)}, _gen_wiretype.MapType{Key: 0x4b, Elem: 0x4c, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
 				_gen_wiretype.FieldType{Type: 0x48, Name: "Config"},
 				_gen_wiretype.FieldType{Type: 0x4a, Name: "RootOID"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "ETag"},
-				_gen_wiretype.FieldType{Type: 0x4a, Name: "SGOID"},
-				_gen_wiretype.FieldType{Type: 0x4d, Name: "Joiners"},
+				_gen_wiretype.FieldType{Type: 0x4d, Name: "SGOID"},
+				_gen_wiretype.FieldType{Type: 0x4e, Name: "Joiners"},
 			},
 			"veyron/services/syncgroup.SyncGroupInfo", []string(nil)},
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}