Index: fedd/compose.py
===================================================================
--- fedd/compose.py	(revision 4d4dde4d8373b8156623629e3bb507e131c9f0b2)
+++ fedd/compose.py	(revision 89e2138bf54420f3c79a0d6386987c1b43f9e822)
@@ -19,9 +19,10 @@
     """
     def __init__(self, name=None, required=False, accepts=None, provides=None,
-	    match=None):
+	    topology=None, match=None):
 	self.name = name
 	self.required = required
 	self.accepts = accepts or []
 	self.provides = provides or []
+	self.topology = None
 	self.match = match
 
@@ -32,8 +33,5 @@
     def to_xml(self):
 	rv = "<constraint>"
-	if isinstance(self.name, tuple):
-	    rv += "<name>%s</name>" % self.name[0]
-	else:
-	    rv += "<name>%s</name>" % self.name
+	rv += "<name>%s</name>" % self.name
 	rv += "<required>%s</required>" % self.required
 	for p in self.provides:
@@ -188,19 +186,4 @@
     return n
 
-def add_interfaces(top, mark):
-    """
-    Add unconnected interfaces to the nodes whose names are keys in the mark
-    dict.  As the interface is added change the name field of the contstraint
-    in mark into a tuple containing the node name, interface name, and topology
-    in which they reside.
-    """
-    for e in top.elements:
-	if e.name in mark:
-	    con = mark[e.name]
-	    ii = make_new_name(set([x.name for x in e.interface]), "inf")
-	    e.interface.append(
-		    topdl.Interface(substrate=[], name=ii, element=e))
-	    con.name = (e.name, ii, top)
-
 def localize_names(top, names, marks):
     """
@@ -225,8 +208,7 @@
 	e.set_attribute('localized_name', e.name)
 	if e.name in names:
-	    nn= make_new_name(names, "computer")
+	    nn= make_new_name(names, "node")
 	    if e.name in marks:
-		n, i, t = marks[e.name].name
-		marks[e.name].name = (nn, i, t)
+		marks[e.name].name = nn
 	    e.name = nn
 	else:
@@ -259,5 +241,5 @@
 		    # within the same topology.  This also excludes matched
 		    # constraints.
-		    if can.name != c.name and can.name[2] != c.name[2] and \
+		    if can.name != c.name and can.topology != c.topology and \
 			    not can.match:
 			# Now check that the candidate also accepts c
@@ -337,33 +319,20 @@
 	    sn = make_new_name(names, "sub")
 	    s = topdl.Substrate(name=sn)
-	    connected = 0
-	    # Walk through all the computers in the topology
+
+	    # These are the nodes that need to be connected.  Put an new
+	    # interface on each one and hook them to the new substrate.
 	    for e in [ e for e in top.elements \
-		    if isinstance(e, topdl.Computer)]:
-		# if the computer matches the computer and interface name in
-		# either c or c.match, connect it.  Once both computers have
-		# been found and connected, exit the loop walking through all
-		# computers.
-		for comp, inf in (c.name[0:2], c.match.name[0:2]):
-		    if e.name == comp:
-			for i in e.interface:
-			    if i.name == inf:
-				i.substrate.append(sn)
-				connected += 1
-				break
-			break
-		# Connected both, so add the substrate to the topology
-		if connected == 2: 
-		    top.substrates.append(s)
-		    break
-	    # c and c.match have been processed, so add them to the done set
+		    if isinstance(e, topdl.Computer) \
+			and e.name in (c.name, c.match.name)]:
+		ii = make_new_name(set([x.name for x in e.interface]), "inf")
+		e.interface.append(
+			topdl.Interface(substrate=[sn], name=ii, element=e))
+
+
+	    # c and c.match have been processed, so add them to the done set,
+	    # and add the substrate
+	    top.substrates.append(s)
 	    done.add(c)
 	    done.add(c.match)
-
-    # All interfaces with matched constraints have been connected.  Cull any
-    # interfaces unassigned to a substrate
-    for e in [ e for e in top.elements if isinstance(e, topdl.Computer)]:
-	if any([ not i.substrate for i in e.interface]):
-	    e.interface = [ i for i in e.interface if i.substrate ]
 
     top.incorporate_elements()
@@ -469,8 +438,9 @@
 	"""
 	print >>f, "<component>"
-	print >>f, "<constraints>"
-	for c in constraints:
-	    print >>f, c.to_xml()
-	print >>f, "</constraints>"
+	if constraints:
+	    print >>f, "<constraints>"
+	    for c in constraints:
+		print >>f, c.to_xml()
+	    print >>f, "</constraints>"
 	print >>f, topdl.topology_to_xml(comp, top='experiment')
 	print >>f, "</component>"
@@ -578,8 +548,9 @@
 	    t = top.clone()
 	    m = copy.deepcopy(marks)
+	    # Bind the constraints in m (the marks copy) to this topology
+	    for c in m.values():
+		c.topology = t
 	    index_constraints(m.values(), provides, accepts)
-	    add_interfaces(t, m)
 	    localize_names(t, names, m)
-	    t.incorporate_elements()
 	    constraints.extend(m.values())
 	    topos.append(t)
@@ -608,11 +579,4 @@
 	import_components(files)
 
-# Let the user know if they messed up on specifying constraints.
-if any([ not isinstance(c.name, tuple) for c in constraints]):
-    warn("nodes not found for constraints on %s" % \
-	    ",".join([ c.name for c in constraints \
-	    if isinstance(c.name, basestring)]))
-    constraints = [ c for c in constraints if isinstance(c.name, tuple )]
-
 # If more than one component was given, actually do the composition, otherwise
 # this is probably a format conversion. 
@@ -643,5 +607,5 @@
     # that had matches.
     comp = topdl.Topology()
-    for t in set([ c.name[2] for c in constraints if c.match]):
+    for t in set([ c.topology for c in constraints if c.match]):
 	comp.elements.extend([e.clone() for e in t.elements])
 	comp.substrates.extend([s.clone() for s in t.substrates])
