Index: fedd/fedd_allocate_project.py
===================================================================
--- fedd/fedd_allocate_project.py	(revision 03e0290ca3c8437abef1a5c25750bc49f5bea8c5)
+++ fedd/fedd_allocate_project.py	(revision e40c7ee7bfc33dc78871eb0edb26487d0974a045)
@@ -88,5 +88,5 @@
 		uid = proj['userID']
 		# XXX: fedid
-		uname = uid.get('username', None) or \
+		uname = uid.get('localname', None) or \
 			uid.get('kerberosUsername', None) or \
 			uid.get('uri', None)
@@ -175,7 +175,7 @@
 	rv = {\
 	    'project': {\
-		'name': { 'username': name }, 
+		'name': { 'localname': name }, 
 		'user' : [ {\
-		    'userID': { 'username' : uname },
+		    'userID': { 'localname' : uname },
 		    'access': [ { 'sshPubkey' : ssh } ],
 		} ]\
Index: fedd/fedd_client.py
===================================================================
--- fedd/fedd_client.py	(revision 03e0290ca3c8437abef1a5c25750bc49f5bea8c5)
+++ fedd/fedd_client.py	(revision e40c7ee7bfc33dc78871eb0edb26487d0974a045)
@@ -99,4 +99,6 @@
 	fedd_client_opts.__init__(self)
 	self.add_option("-e", "--experiment_cert", dest="out_certfile",
+		type="string", help="output certificate file")
+	self.add_option("-E", "--experiment_name", dest="exp_name",
 		type="string", help="output certificate file")
 	self.add_option("-F","--useFedid", action="store_true",
@@ -141,23 +143,4 @@
 		help="Testbed identifier (URI) to contact (required)")
 
-def exit_with_fault(dict, out=sys.stderr):
-    """ Print an error message and exit.
-
-    The dictionary contains the FeddFaultBody elements."""
-    codestr = ""
-
-    if dict.has_key('errstr'):
-	codestr = "Error: %s" % dict['errstr']
-
-    if dict.has_key('code'):
-	if len(codestr) > 0 : 
-	    codestr += " (%d)" % dict['code']
-	else:
-	    codestr = "Error Code: %d" % dict['code']
-
-    print>>out, codestr
-    print>>out, "Description: %s" % dict['desc']
-    sys.exit(dict.get('code', 20))
-
 class fedd_exp_data_opts(fedd_client_opts):
     def __init__(self):
@@ -165,5 +148,25 @@
 	self.add_option("-e", "--experiment_cert", dest="exp_certfile",
 		type="string", help="output certificate file")
-
+	self.add_option("-E", "--experiment_name", dest="exp_name",
+		type="string", help="output certificate file")
+
+def exit_with_fault(dict, out=sys.stderr):
+    """ Print an error message and exit.
+
+    The dictionary contains the FeddFaultBody elements."""
+    codestr = ""
+
+    if dict.has_key('errstr'):
+	codestr = "Error: %s" % dict['errstr']
+
+    if dict.has_key('code'):
+	if len(codestr) > 0 : 
+	    codestr += " (%d)" % dict['code']
+	else:
+	    codestr = "Error Code: %d" % dict['code']
+
+    print>>out, codestr
+    print>>out, "Description: %s" % dict['desc']
+    sys.exit(dict.get('code', 20))
 # Base class that will do a the SOAP/XMLRPC exchange for a request.
 class fedd_rpc:
@@ -171,5 +174,5 @@
 	def __init__(self, fb):
 	    self.desc = fb.get('desc', None)
-	    self.code = fb.get('code', None)
+	    self.code = fb.get('code', -1)
 	    self.errstr = fb.get('errstr', None)
 
@@ -310,5 +313,5 @@
 		method_call = getattr(port, self.method, None)
 		resp = method_call(
-			encapsulate_binaries({ self.RequestBody: msg},\
+			encapsulate_binaries({ self.RequestBody: req_dict},\
 			    ('fedid',)))
 	    except Error, e:
@@ -317,5 +320,6 @@
 	    if resp:
 		if resp.has_key(self.ResponseBody): 
-		    return resp[self.ResponseBody]
+		    return decapsulate_binaries(resp[self.ResponseBody],
+			    ('fedid',))
 		elif resp.has_key('FeddFaultBody'):
 		    raise self.RPCException(resp['FeddFaultBody'])
@@ -387,11 +391,18 @@
 	    sys.exit("Cannot read certificate (%s)" % cert)
 
+	if opts.exp_name and opts.exp_certfile:
+	    sys.exit("Only one of --experiment_cert and " +\
+		    "--experiment_name permitted");
+
 	if opts.exp_certfile:
-	    exp_fedid = fedid(file=opts.exp_certfile)
-	else:
-	    sys.exit("Experiment certfile required")
+	    exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
+
+	if opts.exp_name:
+	    exp_id = { 'localname' : opts.exp_name }
+
+	req = { 'experiment': exp_id }
 
 	try:
-	    resp_dict = self.do_rpc({ 'experiment': { 'fedid': exp_fedid } }, 
+	    resp_dict = self.do_rpc(req,
 		    opts.url, opts.transport, cert, opts.trusted, 
 		    serialize_only=opts.serialize_only,
@@ -401,5 +412,6 @@
 		    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
 	except RuntimeError, e:
-	    sys.exit("Error processing RPC: %s" % e.message)
+	    print e
+	    sys.exit("Error processing RPC: %s" % e)
 
 	try:
@@ -469,4 +481,7 @@
 			} ]
 		}
+
+	if opts.exp_name:
+	    msg['experimentID'] = { 'localname': opts.exp_name }
 
 	if opts.debug > 1: print >>sys.stderr, msg
@@ -493,4 +508,10 @@
 	    except IOError:
 		sys.exit('Could not write to %s' %  out_certfile)
+	eid = resp_dict.get('experimentID', None)
+	if eid:
+	    for id in eid:
+		for k in id.keys():
+		    if k == 'fedid': print "%s: %s" % (k,fedid(bits=id[k]))
+		    else: print "%s: %s" % (k, id[k])
 
 class access(fedd_rpc):
Index: fedd/fedd_create_experiment.py
===================================================================
--- fedd/fedd_create_experiment.py	(revision 03e0290ca3c8437abef1a5c25750bc49f5bea8c5)
+++ fedd/fedd_create_experiment.py	(revision e40c7ee7bfc33dc78871eb0edb26487d0974a045)
@@ -624,5 +624,5 @@
 		'destinationTestbed' : { 'uri' : uri },
 		'user':  user,
-		'allocID' : { 'username': 'test' },
+		'allocID' : { 'localname': 'test' },
 		'access' : [ { 'sshPubkey' : self.ssh_pubkey } ]
 	    }
@@ -1077,8 +1077,4 @@
 	pid = "dummy"
 	gid = "dummy"
-	eid = self.exp_stem
-	if self.randomize_experiments:
-	    for i in range(0,5):
-		eid += random.choice(string.ascii_letters)
 	# XXX
 	fail_soft = False
@@ -1106,4 +1102,18 @@
 	else:
 	    raise service_error(service_error.req, "No experiment description")
+
+	if req.has_key('experimentID') and \
+		req['experimentID'].has_key('localname'):
+	    eid = req['experimentID']['localname']
+	    while (self.state.has_key(eid)):
+		eid += random.choice(string.ascii_letters)
+	else:
+	    eid = self.exp_stem
+	    for i in range(0,5):
+		eid += random.choice(string.ascii_letters)
+	    while (self.state.has_key(eid)):
+		eid = self.exp_stem
+		for i in range(0,5):
+		    eid += random.choice(string.ascii_letters)
 
 	try:
@@ -1172,4 +1182,13 @@
 		    "Failed to generate visualization")
 
+	# save federant information
+	for k in allocated.keys():
+	    tbparams[k]['federant'] = {\
+		    'name': [ { 'localname' : k} ],\
+		    'emulab': tbparams[k]['emulab'],\
+		    'master' : k == master,\
+		}
+
+
 	# Copy tarfiles and rpms needed at remote sites into a staging area
 	try:
@@ -1254,20 +1273,25 @@
 	os.rmdir(tmpdir)
 
-	resp = { 'emulab' : [ tbparams[tb]['emulab'] \
+	resp = { 'federant' : [ tbparams[tb]['federant'] \
 		for tb in tbparams.keys() \
-		    if tbparams[tb].has_key('emulab') ],\
+		    if tbparams[tb].has_key('federant') ],\
 		    'experiment': vtopo,\
 		    'vis' : vis,
-		    'experimentID' : { 'fedid': expid },\
+		    'experimentID' : [\
+			    { 'fedid': expid }, { 'localname': eid },\
+			],\
 		    'experimentAccess': { 'X509' : expcert },\
 		}
 	
 	self.state[expid] = {\
-		'emulab': [ tbparams[tb]['emulab'] \
+		'fedid': expid,
+		'localname': eid,
+		'federant': [ tbparams[tb]['federant'] \
 		    for tb in tbparams.keys() \
-			if tbparams[tb].has_key('emulab') ],\
+			if tbparams[tb].has_key('federant') ],\
 		'vis': vis,\
 		'vtopo': vtopo,\
 	    }
+	self.state[eid] = self.state[expid]
 	    
 	return resp
@@ -1279,12 +1303,20 @@
 	    raise service_error(service_error.req,
 		    "Bad request format (no VtopoRequestBody)")
-	if req.has_key('experiment') and req['experiment'].has_key('fedid'):
-	    qfedid = req['experiment']['fedid']
+	exp = req.get('experiment', None)
+	if exp:
+	    if exp.has_key('fedid'):
+		key = fedid(bits=exp['fedid'])
+		keytype = "fedid"
+	    elif exp.has_key('localname'):
+		key = exp['localname']
+		keytype = "localname"
+	    else:
+		raise service_error(service_error.req, "Unknown lookup type")
 	else:
-	    raise service_error(service_error.req, "Use fedid for lookup")
-
-	if self.state.has_key(qfedid):
-	    return { 'experiment' : {'fedid': qfedid },\
-		    'vtopo': self.state[qfedid]['vtopo'],\
+	    raise service_error(service_error.req, "No request?")
+
+	if self.state.has_key(key):
+	    return { 'experiment' : {keytype: key },\
+		    'vtopo': self.state[key]['vtopo'],\
 		    }
 	else:
@@ -1297,12 +1329,20 @@
 	    raise service_error(service_error.req,
 		    "Bad request format (no VisRequestBody)")
-	if req.has_key('experiment') and req['experiment'].has_key('fedid'):
-	    qfedid = req['experiment']['fedid']
+	exp = req.get('experiment', None)
+	if exp:
+	    if exp.has_key('fedid'):
+		key = fedid(bits=exp['fedid'])
+		keytype = "fedid"
+	    elif exp.has_key('localname'):
+		key = exp['localname']
+		keytype = "localname"
+	    else:
+		raise service_error(service_error.req, "Unknown lookup type")
 	else:
-	    raise service_error(service_error.req, "Use fedid for lookup")
-
-	if self.state.has_key(qfedid):
-	    return { 'experiment' : {'fedid': qfedid },\
-		    'vis': self.state[qfedid]['vis'],\
+	    raise service_error(service_error.req, "No request?")
+
+	if self.state.has_key(key):
+	    return { 'experiment' : {keytype: key },\
+		    'vis': self.state[key]['vis'],\
 		    }
 	else:
@@ -1366,5 +1406,5 @@
 	    'experimentdescription' : content, 
 	    'master' : opts.master, 
-	    'user': [ {'userID' : { 'username' : 'faber' } } ],
+	    'user': [ {'userID' : { 'localname' : 'faber' } } ],
 	    },
 	    None)
Index: fedd/fedd_proj.py
===================================================================
--- fedd/fedd_proj.py	(revision 03e0290ca3c8437abef1a5c25750bc49f5bea8c5)
+++ fedd/fedd_proj.py	(revision e40c7ee7bfc33dc78871eb0edb26487d0974a045)
@@ -502,7 +502,7 @@
 		    # XXX ssh key additions
 		    ap = { 'project': \
-			    { 'name' : { 'username' : found[0].name },\
+			    { 'name' : { 'localname' : found[0].name },\
 			      'user' : [ {\
-				'userID': { 'username' : found[1] }, \
+				'userID': { 'localname' : found[1] }, \
 				'access': [ { 'sshPubkey': s } for s in ssh]}\
 				]\
@@ -636,5 +636,5 @@
 
 	if msg != None:
-	    return encapsulate_binaries({ "VtoposResponseBody" : msg },
+	    return encapsulate_binaries({ "VisResponseBody" : msg },
 		    ('fedid',))
 	else:
Index: fedd/fedd_types.xsd
===================================================================
--- fedd/fedd_types.xsd	(revision 03e0290ca3c8437abef1a5c25750bc49f5bea8c5)
+++ fedd/fedd_types.xsd	(revision e40c7ee7bfc33dc78871eb0edb26487d0974a045)
@@ -15,5 +15,5 @@
       <xsd:element name="fedid" type="xsd:base64Binary"/>
       <xsd:element name="uri" type="xsd:string"/>
-      <xsd:element name="username" type="xsd:string"/>
+      <xsd:element name="localname" type="xsd:string"/>
       <xsd:element name="kerberosUsername" type="xsd:string"/>
     </xsd:choice>
@@ -157,4 +157,19 @@
     </xsd:sequence>
   </xsd:complexType>
+
+  <xsd:complexType name="federatedExperimentType">
+    <xsd:annotation>
+      <xsd:documentation>
+	The information about a federated sub-experiment
+      </xsd:documentation>
+    </xsd:annotation>
+    <xsd:sequence>
+      <xsd:element name="name" type="tns:IDType" minOccurs="1" 
+	maxOccurs="unbounded"/>
+      <xsd:element name="emulab" type="tns:emulabType"/>
+      <xsd:element name="master" type="xsd:boolean"/>
+    </xsd:sequence>
+  </xsd:complexType>
+
 
   <xsd:complexType name="vtoponodeType">
@@ -304,4 +319,6 @@
       <xsd:element name="experimentdescription" type="xsd:base64Binary"/>
       <xsd:element name="master" type="xsd:string"/>
+      <xsd:element name="experimentID" type="tns:IDType" minOccurs="0" 
+	maxOccurs="1"/>
     </xsd:sequence>
   </xsd:complexType>
@@ -314,11 +331,12 @@
     </xsd:annotation>
     <xsd:sequence>
-      <xsd:element name="emulab" type="tns:emulabType" minOccurs="1" 
-	maxOccurs="unbounded"/>
+      <xsd:element name="federant" type="tns:federatedExperimentType" 
+        minOccurs="1" maxOccurs="unbounded"/>
       <xsd:element name="experiment" type="tns:vtopoType" minOccurs="0"
 	maxOccurs="1"/>
       <xsd:element name="vis" type="tns:visType" minOccurs="0"
 	maxOccurs="1"/>
-      <xsd:element name="experimentID" type="tns:IDType"/>
+      <xsd:element name="experimentID" type="tns:IDType" minOccurs="1"
+	maxOccurs="unbounded"/>
       <xsd:element name="experimentAccess" type="tns:accessType" minOccurs="0"
 	maxOccurs="1"/>
Index: fedd/fedd_util.py
===================================================================
--- fedd/fedd_util.py	(revision 03e0290ca3c8437abef1a5c25750bc49f5bea8c5)
+++ fedd/fedd_util.py	(revision e40c7ee7bfc33dc78871eb0edb26487d0974a045)
@@ -169,5 +169,5 @@
     if isinstance(id, type(fedid())): return { 'fedid': id }
     elif id.startswith("http:") or id.startswith("https:"): return { 'uri': id }
-    else: return { 'username': id}
+    else: return { 'localname': id}
 
 def unpack_id(id):
@@ -175,5 +175,5 @@
     if id.has_key("fedid"): return fedid(id["fedid"])
     else:
-	for k in ("username", "uri", "kerberosUsername"):
+	for k in ("localname", "uri", "kerberosUsername"):
 	    if id.has_key(k): return id[k]
     return None
