Index: fedd/federation/experiment_control.py
===================================================================
--- fedd/federation/experiment_control.py	(revision 80b1e822407935684cb8c2dbf7f2d69a5b0a51c6)
+++ fedd/federation/experiment_control.py	(revision 9294673d8c09127f7891dc55c97705a88e67e3cd)
@@ -960,5 +960,5 @@
 	    tb_attrs = copy.copy(attrs)
 	    tp.wait_for_slot()
-	    uri = tbparams[tb].get('uri', tbmap.get(testbed_base(tb), None))
+	    uri = tbparams[tb].uri or tbmap.get(testbed_base(tb), None)
 	    base, suffix = split_testbed(tb)
 	    if suffix:
@@ -971,8 +971,6 @@
 			"Unknown testbed %s !?" % tb)
 
-	    if tbparams[tb].has_key('allocID') and \
-		    tbparams[tb]['allocID'].has_key('fedid'):
-		aid = tbparams[tb]['allocID']['fedid']
-	    else:
+	    aid = tbparams[tb].allocID
+	    if not aid:
 		raise service_error(service_error.internal, 
 			"No alloc id for testbed %s !?" % tb)
@@ -1021,5 +1019,5 @@
                     # Create and start a thread to stop the segment
                     tp.wait_for_slot()
-		    uri = tbparams[tb]['uri']
+		    uri = tbparams[tb].uri
                     t  = pooled_thread(\
                             target=self.terminate_segment(log=log,
@@ -1029,5 +1027,5 @@
 				trusted_certs=self.trusted_certs,
 				caller=self.call_TerminateSegment),
-                            args=(uri, tbparams[tb]['federant']['allocID']),
+                            args=(uri, tbparams[tb].allocID),
 			    name=tb,
                             pdata=tp, trace_file=self.trace_file)
@@ -1040,6 +1038,6 @@
                 for tb in tbparams.keys():
 		    try:
-			self.release_access(tb, tbparams[tb]['allocID'], 
-				tbmap=tbmap, uri=tbparams[tb].get('uri', None),
+			self.release_access(tb, tbparams[tb].allocID, 
+				tbmap=tbmap, uri=tbparams[tb].uri,
 				cert_file=cert, cert_pwd=pw)
 		    except service_error, e:
@@ -1386,9 +1384,6 @@
                         "Bad access response (no access proof)")
         
-	tbparam[tb] = { 
-		"allocID" : r['allocID'],
-		"uri": uri,
-		"proof": [ r['proof'] ],
-		}
+	tbparam[tb] = allocation_info(allocID=r['allocID'].get('fedid', None),
+		tb=tb, uri=uri, proof=[r['proof']])
 
 	# Collect the responses corresponding to the services this testbed
@@ -1405,8 +1400,6 @@
 	for a in r.get('fedAttr', []):
 	    try:
-		if a['attribute'] and \
-			isinstance(a['attribute'], basestring)\
-			and not tbparam[tb].has_key(a['attribute'].lower()):
-		    tbparam[tb][a['attribute'].lower()] = a['value']
+		if a['attribute']:
+		    tbparam[tb].set_attribute(a['attribute'], a['value'])
 	    except KeyError:
 		self.log.error("Bad attribute in response: %s" % a)
@@ -1525,5 +1518,5 @@
 	    # the loop.
 	    auth_attrs.update([
-		(tbparams[tb]['allocID']['fedid'], "/%s/%s" % ( path, dest)) \
+		(tbparams[tb].allocID, "/%s/%s" % ( path, dest)) \
 			for tb in tbparams.keys()])
 
@@ -1829,5 +1822,5 @@
 	# allocation principal.  Yeah, that's a long list comprehension.
 	self.append_experiment_authorization(expid, set([
-	    (tbparams[tb]['allocID']['fedid'], "%s/%s" % (configpath, f)) \
+	    (tbparams[tb].allocID, "%s/%s" % (configpath, f)) \
 		    for tb in tbparams.keys() \
 			for f in ("hosts", 'ca.pem', 'node.pem', 
@@ -1982,15 +1975,9 @@
 	# save federant information
 	for k in allocated.keys():
-	    exp.add_allocation(
-		    allocation_info(
-			tb=k, 
-			allocID=tbparams[k]['allocID'].get('fedid', None),
-			uri=tbparams[k]['uri'],
-			proof=tbparams[k]['proof'])
-		    )
+	    exp.add_allocation(tbparams[k])
 
 	# Access proofs for the response message
 	proofs = [copy.deepcopy(p) for k in tbparams.keys()\
-		    for p in tbparams[k]['proof']]
+		    for p in tbparams[k].proof]
 	if self.state_filename: 
 	    self.write_state()
@@ -2105,5 +2092,5 @@
 		if store_keys:
 		    auth_attrs.update(set([
-			(tbparams[tb]['allocID']['fedid'], sk) \
+			(tbparams[tb].allocID, sk) \
 				for sk in store_keys.split(" ")]))
 
Index: fedd/federation/experiment_info.py
===================================================================
--- fedd/federation/experiment_info.py	(revision 80b1e822407935684cb8c2dbf7f2d69a5b0a51c6)
+++ fedd/federation/experiment_info.py	(revision 9294673d8c09127f7891dc55c97705a88e67e3cd)
@@ -14,4 +14,13 @@
 	self.uri = uri
 	self.proof = proof
+	self.attrs = { }
+
+    def set_attribute(self, a, v):
+	a = a.lower()
+	if a not in self.attrs: self.attrs[a] = v
+
+    def get_attribute(self, a, default=None):
+	a = a.lower()
+	return self.attrs.get(a, default)
 
 class experiment_info:
Index: fedd/federation/experiment_partition.py
===================================================================
--- fedd/federation/experiment_partition.py	(revision 80b1e822407935684cb8c2dbf7f2d69a5b0a51c6)
+++ fedd/federation/experiment_partition.py	(revision 9294673d8c09127f7891dc55c97705a88e67e3cd)
@@ -74,8 +74,10 @@
 
 	if seer_master:
-	    mdomain = tbparams[seer_master].get('domain', '.example.com')
-	    mproject = tbparams[seer_master].get('project', 'project')
-	    muser = tbparams[seer_master].get('user', 'root')
-	    smbshare = tbparams[seer_master].get('smbshare', 'USERS')
+	    mdomain = tbparams[seer_master].get_attribute('domain', 
+		    '.example.com')
+	    mproject = tbparams[seer_master].get_attribute('project', 
+		    'project')
+	    muser = tbparams[seer_master].get_attribute('user', 'root')
+	    smbshare = tbparams[seer_master].get_attribute('smbshare', 'USERS')
 	else:
 	    mdomain = '.example.com'
@@ -84,6 +86,6 @@
 	    smbshare = 'USERS'
 
-	dproject = tbparams[dt].get('project', 'project')
-	ddomain = tbparams[dt].get('domain', '.example.com')
+	dproject = tbparams[dt].get_attribute('project', 'project')
+	ddomain = tbparams[dt].get_attribute('domain', '.example.com')
 
 	if (st in masters and dt not in masters) or \
@@ -108,5 +110,5 @@
 	if conn_type == "ssh":
 	    try:
-		aid = tbparams[st]['allocID']['fedid']
+		aid = tbparams[st].allocID
 	    except:
 		self.log.debug("[new_portal_node] Can't get alloc id for %s?" \
@@ -178,6 +180,6 @@
 
     def new_portal_substrate(self, st, dt, eid, tbparams, expid):
-	ddomain = tbparams[dt].get('domain', ".example.com")
-	dproject = tbparams[dt].get('project', 'project')
+	ddomain = tbparams[dt].get_attribute('domain', ".example.com")
+	dproject = tbparams[dt].get_attribute('project', 'project')
 	tsubstrate = \
 		topdl.Substrate(name='%s-%s' % (st, dt),
@@ -189,5 +191,5 @@
 			)
 	segment_element = topdl.Segment(
-		id= tbparams[dt]['allocID'],
+		id= {'fedid': tbparams[dt].allocID },
 		type='emulab',
 		uri = self.tbmap.get(testbed_base(dt), None),
@@ -222,5 +224,5 @@
 	for tb in tbs.keys():
 	    seg = topdl.Segment(
-		    id = tbparams[tb]['allocID'],
+		    id = { 'fedid':tbparams[tb].allocID },
 		    type='emulab',
 		    uri = self.tbmap.get(testbed_base(tb), None),
@@ -231,10 +233,11 @@
 		    attribute=[ topdl.Attribute(
 			attribute='%s_endpoint' % tb_name, 
-			value=tbparams[tb][tb_name]),
+			value=tbparams[tb].get_attribute(tb_name)),
 			]
 		    )
 	    vlan_key = "%s_vlans" % tb_name
-	    if vlan_key in tbparams[tb]:
-		seg.set_attribute(vlan_key, tbparams[tb][vlan_key])
+	    if tbparams[tb].get_attribute(vlan_key) is not None:
+		seg.set_attribute(vlan_key, 
+			tbparams[tb].get_attribute(vlan_key))
 	    segs.append(seg)
 
@@ -242,5 +245,5 @@
 	    # vlan_id
 	    try:
-		aid = tbparams[tb]['allocID']['fedid']
+		aid = tbparams[tb].allocID
 		self.auth.set_attribute(aid, store_key)
 	    except:
@@ -292,6 +295,7 @@
 
 	if seer_master:
-	    mdomain = tbparams[seer_master].get('domain', '.example.com')
-	    mproject = tbparams[seer_master].get('project', 'project')
+	    mdomain = tbparams[seer_master].get_attribute('domain',
+		    '.example.com')
+	    mproject = tbparams[seer_master].get_attribute('project', 'project')
 	else:
 	    mdomain = '.example.com'
@@ -311,5 +315,5 @@
 
 		try:
-		    aid = tbparams[tb]['allocID']['fedid']
+		    aid = tbparams[tb].allocID
 		except:
 		    self.log.debug("[create_direct_substrate] " + 
@@ -370,9 +374,9 @@
 		connInfo[st] = [ ]
 	    for dt in [ t for t in tbs.keys() if t != st]:
-		sproject = tbparams[st].get('project', 'project')
-		dproject = tbparams[dt].get('project', 'project')
-		sdomain = tbparams[st].get('domain', ".example.com")
-		ddomain = tbparams[dt].get('domain', ".example.com")
-		aid = tbparams[dt]['allocID']['fedid']
+		sproject = tbparams[st].get_attribute('project', 'project')
+		dproject = tbparams[dt].get_attribute('project', 'project')
+		sdomain = tbparams[st].get_attribute('domain', ".example.com")
+		ddomain = tbparams[dt].get_attribute('domain', ".example.com")
+		aid = tbparams[dt].allocID
 
 		seer_master = None
@@ -386,8 +390,11 @@
 
 		if seer_master:
-		    mdomain = tbparams[seer_master].get('domain', '.example.com')
-		    mproject = tbparams[seer_master].get('project', 'project')
-		    muser = tbparams[seer_master].get('user', 'root')
-		    smbshare = tbparams[seer_master].get('smbshare', 'USERS')
+		    mdomain = tbparams[seer_master].get_attribute('domain',
+			    '.example.com')
+		    mproject = tbparams[seer_master].get_attribute('project', 
+			    'project')
+		    muser = tbparams[seer_master].get_attribute('user', 'root')
+		    smbshare = tbparams[seer_master].get_attribute('smbshare',
+			    'USERS')
 		else:
 		    mdomain = '.example.com'
@@ -541,5 +548,5 @@
 		# transits is applicable, use the internet.
 		for d in self.direct_transit:
-		    if all([tbparams[x].has_key(d) for x in tbs]):
+		    if all([tbparams[x].get_attribute(d) for x in tbs]):
 			self.create_direct_substrate(s, topo, tbs, tbparams, 
 				masters, eid, connInfo, expid, d)
@@ -574,6 +581,6 @@
 		    for tb_name in self.direct_transit:
 
-			if tbparams[mtb].has_key(tb_name) \
-				and tbparams[tb].has_key(tb_name):
+			if tbparams[mtb].get_attribute(tb_name) \
+				and tbparams[tb].get_attribute(tb_name):
 
 			    idx = len([x for x in topo.keys() \
@@ -593,5 +600,5 @@
 				    )
 			    seg = topdl.Segment(
-				    id= tbparams[mtb]['allocID'],
+				    id= {'fedid': tbparams[mtb].allocID},
 				    type='emulab',
 				    uri = self.tbmap.get(testbed_base(mtb),
@@ -605,8 +612,9 @@
 					    for n, v in (\
 						('domain', 
-						    tbparams[mtb].get('domain',
+						    tbparams[mtb].getattribute(
+							'domain',
 							".example.com")),
 						('experiment', "%s/%s" % \
-							(tbparams[mtb].get(
+							(tbparams[mtb].get_attribute(
 							    'project', 
 							    'project'), 
@@ -623,5 +631,5 @@
 			    mcsub = csub.clone()
 			    seg = topdl.Segment(
-				    id= tbparams[tb]['allocID'],
+				    id= { 'fedid': tbparams[tb].allocID},
 				    type='emulab',
 				    uri = self.tbmap.get(testbed_base(tb),
@@ -635,8 +643,10 @@
 					    for n, v in (\
 						('domain', 
-						    tbparams[tb].get('domain',
+						    tbparams[tb].get_attribute(
+							'domain',
 							".example.com")),
 						('experiment', "%s/%s" % \
-							(tbparams[tb].get('project', 
+							(tbparams[tb].get_attribute(
+							    'project', 
 							    'project'), 
 							    eid)),)
