Index: fedd/abac-src/ttg/process/ACPolicy.java
===================================================================
--- fedd/abac-src/ttg/process/ACPolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/ACPolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,60 @@
+package com.nailabs.abac.process;
+
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+
+/**
+ * Access control policy for credentials. The policy can be queried using the 
+ * <code>requires</code> method with a specific credential. 
+ */
+public class ACPolicy implements java.io.Serializable {
+    /** Implicitly allow access if there is no relevant policy */
+    public static final Role TRUE = null;
+
+    /** Internal hash table for policy storage */
+    private HashMap accessControl = null;
+
+    /** Default constructor with a non-resstrictive policy */
+    public ACPolicy() {
+	accessControl = new HashMap();
+    }
+
+    /** Accessor for all the access control policy keys */
+    public Vector getProtectedCredentials() { 
+        return new Vector(accessControl.keySet()); 
+    }
+
+    /** 
+     * Useful for forward discovery. 
+     * @return a set of all roles which satisfy the AC policy requirements
+     */
+    public Vector getRequiredRoles() {
+	return new Vector(accessControl.values());
+    }
+
+    /** Adds a single policy atom from String parameters. */
+    public void addACFact(String cred, String expr) 
+	throws CredentialParsingException {
+	addACFact(new StaticCredential(cred), 
+	     StaticCredential.getEntityExpression(expr));
+    }
+
+    /** Adds a single policy atom. */
+    public void addACFact(Credential key, EntityExpression expr) {
+	accessControl.put(key, expr);
+    }
+
+    /** Query the policy to determine the required role for a credential */
+    public EntityExpression requires(Credential resource) {
+	return (EntityExpression)accessControl.get(resource);
+    }
+
+    /** Returns the underlying storage data structure in a printable format */
+    public String toString() {
+	if(accessControl == null)
+	    return null;
+	else 
+	    return accessControl.toString();
+    }
+
+}
Index: fedd/abac-src/ttg/process/AckFact.java
===================================================================
--- fedd/abac-src/ttg/process/AckFact.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/AckFact.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,121 @@
+package com.nailabs.abac.process;
+
+import edu.stanford.peer.rbtm.credential.*;
+
+public class AckFact {
+
+    /**
+     * This attribute defines the scope of the AckFact instance.
+     */
+    protected EntityExpression attribute;
+
+    /**
+     * Optional string meta-identifier for the value field.
+     */
+    protected String field;
+
+    /**
+     * Optional value corresponding to the named field.
+     */
+    protected Object value;
+
+    /**
+     * The credential role required to match with the requesting subject.
+     */
+    protected EntityExpression requirement;
+    
+    /**
+     * A constant to represent a default value (aka a wildcard).
+     */
+    static final String DEFAULT = "default";
+
+    /**
+     * A true constant for denoting that no requirements are necessary. 
+     * This can also be implicitly represented as a null requirement.
+     */
+    static final String TRUE = "true";
+
+    /**
+     * Basic constructor method. This method subtitutes a default key-value
+     * pair.
+     */
+    public AckFact(EntityExpression attribute, EntityExpression req) {
+	this(attribute, DEFAULT, DEFAULT, req);
+    }
+
+    /**
+     * Explicit constructor method. This represents a fully expanded policy
+     * fact.
+     */
+    public AckFact(EntityExpression attr,String key,Object val,EntityExpression req) {
+	attribute = attr;
+	field = key;
+	value = val;
+	requirement = req;
+    }
+
+
+    /**
+     * An accessor method for the attribute which needs to be unlocked. 
+     * <B> This is private policy information and should not be xmitted </B>
+     */
+    public RoleName getAttribute() { 
+        if(attribute instanceof Role) {
+            return ((Role)attribute).getName(); 
+        }
+        else if(attribute instanceof LinkedRole) {        
+            return ((LinkedRole)attribute).getFirstRole().getName();
+        }
+        else {
+            return null;
+        }
+    }
+
+    /**
+     * An accessor method for the optional special case meta-type.
+     * <B> This is private policy information and should not be xmitted </B>
+     */
+    public String getField() { return field; }
+
+    /**
+     * An accessor method for the optional special case value.
+     * <B> This is private policy information and should not be xmitted </B>
+     */
+    public Object getValue() { return value; }
+
+    /**
+     * An accessor method for an expression which can unlocked the attribute
+     * if the expression is proved to be true.
+     * <B> This is public policy information but if transmitted may indicate
+     * that particular credential is possessed.</B>
+     */
+    public EntityExpression getRequirement() { return requirement; }
+
+    /**
+     * Unique hash function, which is based on the attribute's hash code.
+     */
+    public int hashCode() { return attribute.hashCode(); }
+
+    /** 
+     * Tabular printout of the fact in the following order: attribute,
+     * field, value, and attribute expression. The list is comma delimited.
+     */
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[AckFact ");
+	String separator = ", ";
+	buff.append(attribute).append(separator);
+	buff.append(field).append(separator);
+	buff.append(value).append(separator);
+	buff.append(requirement).append("]");
+	return buff.toString();
+    }
+
+}
+
+
+
+
+
+
+
+
Index: fedd/abac-src/ttg/process/AckPolicy.java
===================================================================
--- fedd/abac-src/ttg/process/AckPolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/AckPolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,58 @@
+package com.nailabs.abac.process;
+
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+
+/**
+ * The acknowledgement policy specifies which opponents can be allowed
+ * to receive acknowledgement of credentials possessed by this negotiator.
+ */
+public class AckPolicy implements edu.stanford.peer.rbtm.RBTMConstants,
+				  java.io.Serializable {
+    /** The policy data store */
+    public HashMap factMap = new HashMap(FACT_MAP_SIZE);
+    
+    /** Add a fact from the supplied strings */
+    public void addAckFact(String base, String roleName, String expr) {
+	try {
+	    factMap.put(new Role(base, roleName), 
+			StaticCredential.getEntityExpression(expr));
+	}
+	catch(Exception ex) {
+	    if(DEBUG)ex.printStackTrace();
+	}
+    }
+    
+    /** Add a fact from the supplied object */
+    public void addAckFact(EntityExpression role, EntityExpression req) {
+	factMap.put(role, new AckFact(role, req));
+    }
+
+    /** Return a vector of sensitive roles for the predicate */
+    public Vector getSensitiveRoles() {
+	return new Vector(factMap.keySet());
+    }
+
+    /** 
+     * Useful for forward discovery. 
+     * @return a set of all roles which satisfy the sensitive requirements
+     */
+    public Vector getRequiredRoles() {
+	return new Vector(factMap.values());
+    }
+
+    /** Query policy for the required role to unlock the role expression */
+    public EntityExpression requires(EntityExpression key) {
+	AckFact fact = (AckFact)factMap.get((Object)key);
+	if(fact == null)
+	    return null;
+	else
+	    return (EntityExpression)fact.getRequirement();
+    }
+
+    /** Returns the underlying storage data structure in a printable format */
+    public String toString() {
+	return factMap.toString();
+    }
+
+}
Index: fedd/abac-src/ttg/process/CVS/Entries
===================================================================
--- fedd/abac-src/ttg/process/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,27 @@
+/ACPolicy.java/1.4/Thu Jul  3 17:04:38 2003//
+/AckFact.java/1.8/Thu Sep 19 23:54:59 2002//
+/AckPolicy.java/1.8/Thu Jul  3 17:04:38 2003//
+/ControlEdge.java/1.10/Tue Oct 15 18:51:38 2002//
+/CountTable.java/1.2/Wed Dec  4 22:28:10 2002//
+/EdgeOperation.java/1.19/Tue Apr  8 23:35:30 2003//
+/FrontierManager.java/1.34/Wed Feb 26 00:47:12 2003//
+/ImplicationEdge.java/1.21/Wed Oct 16 16:11:45 2002//
+/IntersectionEdge.java/1.3/Wed Oct 16 16:18:47 2002//
+/LinkingImplicationEdge.java/1.2/Mon Oct 21 18:49:47 2002//
+/LinkingMonitorEdge.java/1.3/Mon Oct 21 18:49:47 2002//
+/LinkingSolutionEdge.java/1.4/Mon Oct 21 18:49:47 2002//
+/Message.java/1.15/Tue Apr  8 23:35:30 2003//
+/NegotiationContext.java/1.12/Wed Nov 13 01:30:42 2002//
+/Negotiator.java/1.4/Thu Aug  1 17:57:11 2002//
+/NodeOperation.java/1.20/Tue Oct 15 19:08:41 2002//
+/Operation.java/1.2/Mon May  6 17:46:43 2002//
+/RMINegotiator.java/1.19/Wed Oct 16 16:08:18 2002//
+/ResourcePolicy.java/1.2/Fri Jul  4 00:06:23 2003//
+/SatisfactionListener.java/1.4/Wed Feb 20 00:51:07 2002//
+/StingyStrategy.java/1.25/Thu Jan 16 01:18:13 2003//
+/Strategy.java/1.24/Thu Jan 16 01:18:13 2003//
+/StrategyFactory.java/1.3/Wed Nov 20 02:04:32 2002//
+/TTG.java/1.50/Wed Feb 26 00:45:11 2003//
+/WeightTable.java/1.8/Wed Nov 20 02:04:32 2002//
+/package.html/1.1/Thu Feb 21 21:26:55 2002//
+D
Index: fedd/abac-src/ttg/process/CVS/Repository
===================================================================
--- fedd/abac-src/ttg/process/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+ttg/process
Index: fedd/abac-src/ttg/process/CVS/Root
===================================================================
--- fedd/abac-src/ttg/process/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/ttg/process/ControlEdge.java
===================================================================
--- fedd/abac-src/ttg/process/ControlEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/ControlEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,48 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import edu.stanford.peer.rbtm.credential.*;
+import java.util.*;
+
+/**
+ * A control edge represents an edge in a trust target graph (<CODE>TTG</CODE>)
+ * with the required roles to support this edge. 
+ */
+public class ControlEdge extends EdgeOperation {
+    /** Jared: Added this method to make XML processing easier */
+    public ControlEdge() {
+        super();
+        type = "Control";
+    }
+    
+    public ControlEdge(Goal parent, Goal child, ProcessingState state) {
+	super(parent, child, state, null);
+	type = "Control";
+    }
+    
+    public void performAdditional(TTG graph) {
+	SimpleTTNode parent = (SimpleTTNode)graph.getNodeByHash(getParent());
+	TargetNode child = (TargetNode)graph.getNodeByHash(getChild());
+
+	parent.addControlChild(child);
+	child.addControlParent(parent);
+    }
+    
+    public void performNewAdditional(TTG graph) {
+	TargetNode child = (TargetNode)graph.getNodeByHash(getChild());
+	if(child == null) {
+	    child = (TargetNode)TTGNode.createNode(getChild());
+	    child.getProcessingState().update(state);
+	    graph.putNodeByHash(child);
+	}
+	performAdditional(graph); 
+    }
+
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[ControlEdge  ");
+	buff.append(getParent()).append(" <<=== ");
+	buff.append(getChild()).append(", state = ");
+	buff.append(state).append("]");
+	return buff.toString();
+    }
+}
Index: fedd/abac-src/ttg/process/CountTable.java
===================================================================
--- fedd/abac-src/ttg/process/CountTable.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/CountTable.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,71 @@
+package com.nailabs.abac.process;
+
+import edu.stanford.peer.rbtm.credential.*;
+import java.util.*;
+import java.io.*;
+
+public class CountTable {
+
+    protected Hashtable table = new Hashtable(20);
+
+    public float SAT = 4.0f;
+
+    public float INIT = 7.0f;
+
+    public CountTable(String file) { load(file);  }
+
+    public void load(String filename) {
+        try {
+            BufferedReader in = new BufferedReader(new FileReader(filename));
+            while(true) {
+                String line = in.readLine();
+                StringTokenizer st = new StringTokenizer(line, "=");
+                EntityExpression expr = 
+                    StaticCredential.getEntityExpression(st.nextToken());
+                Float weight = new Float(st.nextToken());
+                table.put(expr, weight);
+            }
+        } catch(Exception ex) {
+            //ex.printStackTrace();
+        }
+    }
+  
+    public void save(String filename) {
+        try {
+            PrintStream out = new PrintStream(new FileOutputStream(filename));
+            Iterator i = table.keySet().iterator();
+            while(i.hasNext()) {
+                EntityExpression key = (EntityExpression)i.next();
+                Float entry = (Float)table.get(key);
+                out.println(key + "=" + getWeight(key));
+            }
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    public float getWeight(EntityExpression r) {
+        Float val = (Float)table.get(r);
+        if(val == null) {
+            val = new Float(INIT); 
+            table.put(r, val);
+        }
+        return val.floatValue();
+    }
+
+    public void addSatisfied(EntityExpression r) { 
+        Float val =  (Float)table.get(r);
+        if(val == null) {
+            val = new Float(INIT);
+        }
+        val = new Float(SAT);
+        table.put(r, val);
+    }
+
+    public void addFailed(EntityExpression r) {
+        Float val =  (Float)table.get(r);
+        float f = (val == null)? INIT: val.floatValue();
+        f = (f <= 1.0f)?  0.0f: (f - 1.0f); 
+        table.put(r, new Float(f));
+    }
+}
Index: fedd/abac-src/ttg/process/EdgeOperation.java
===================================================================
--- fedd/abac-src/ttg/process/EdgeOperation.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/EdgeOperation.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,144 @@
+package com.nailabs.abac.process;
+
+import edu.stanford.peer.rbtm.credential.*;
+import com.nailabs.abac.trust.*;
+import java.util.*;
+
+public abstract class EdgeOperation implements Operation {
+    /** the parent node of the edge (beginning point) */
+    private Goal parent;
+
+    /** the child node of the edge (end point) */
+    private Goal child;
+
+    private transient HashSet evidence;
+
+    protected String type;
+
+    protected ProcessingState state; 
+
+    public EdgeOperation(Goal p, Goal c, ProcessingState s, HashSet list) {
+	parent = p;
+	child = c;
+	evidence = list;
+	state = s;
+    }
+
+    
+    /** Constructor method  to make XML processing easier */
+    public EdgeOperation() {
+        parent = null;
+        child = null;
+        evidence = null;
+        state = null;
+    }
+    
+    /** 
+     * Modifier method for the setting the parent node of an edge.
+     * Added this method to make XML processing easier 
+     */
+    public void setParent(Goal p) { parent = p; }
+    
+    /** 
+     * Modifier method for setting the child node of an edge.
+     * Added this method to make XML processing easier 
+     */
+    public void setChild(Goal c) { child = c; }
+    
+    /** 
+     * Modifier method for setting the processing state of the child node. 
+     * Added this method to make XML processing easier 
+     */
+    public void setProcessingState(ProcessingState s) { state = s; }
+
+    public final boolean hasNewChild() { return (state != null); }
+
+    public final void perform(TTG graph) {
+	if(hasNewChild())
+	    performNewAdditional(graph);
+	else
+	    performAdditional(graph);
+    }
+
+    public Goal getParent() { return parent; }
+
+    public Goal getChild() { return child; }
+
+    public String getType() { return type; }
+
+    public ProcessingState getProcessingState() { return state; }
+
+    public HashSet getEvidence() { return evidence; }
+
+    public void setEvidence(HashSet set) { evidence = set; }
+
+    public abstract void performAdditional(TTG graph);
+    
+    public abstract void performNewAdditional(TTG graph);
+
+    protected String performNewInfo() {
+	StringBuffer buff = new StringBuffer("adding new child for ");
+	buff.append(getChild().toString());
+	return buff.toString();
+    }
+
+    public String toXML() {
+	return toXML("");
+    }
+
+    protected String toXML(String args) {
+	StringBuffer buff = new StringBuffer("<EdgeOperation type=\"");
+	buff.append(type).append("\" newChild=\"");
+	buff.append(hasNewChild()).append("\"");
+	buff.append(args);
+	buff.append(">\n");
+	if(getParent() != null) {
+	    buff.append("<Parent>\n");
+	    buff.append(getParent().toXML());
+	    buff.append("</Parent>\n");
+	}
+	if(getChild() != null) {
+	    buff.append("<Child>\n");
+	    buff.append(getChild().toXML());
+	    buff.append("</Child>\n");
+	}
+	if(state != null) 
+	    buff.append(state.toXML());
+	//if(evidence != null) {
+	if(false) {
+	    int count = 0;
+	    Iterator i = evidence.iterator();
+	    StringBuffer creds = new StringBuffer();
+	    for(count = 0;i.hasNext();count++) {
+		try {
+		    StaticCredential cred = (StaticCredential)i.next();
+		    //creds.append("<Credential>");
+		    //creds.append(cred.toXML());
+		    //creds.append("</Credential>\n");
+		}
+		catch(Exception ex) {
+		    //ex.printStackTrace();
+		}
+		if(count > 0) {
+		    //buff.append("<Evidence count=\"").append(++count);
+		    //buff.append("\">\n");
+		    //buff.append(creds.toString());
+		    //buff.append("</Evidence>\n");
+		}
+	    }
+	}
+	buff.append("</EdgeOperation>\n");
+	return buff.toString();
+    }
+
+    /** convert this edge into a human-readable formatted String */
+    public String toString() {
+        StringBuffer buff = new StringBuffer("[");
+        buff.append(type).append("Edge");
+        buff.append(getParent()).append(" <<=== ");
+        buff.append(getChild()).append(", state = ");
+        buff.append(state).append("]");
+        return buff.toString();
+    }
+
+}
Index: fedd/abac-src/ttg/process/FrontierManager.java
===================================================================
--- fedd/abac-src/ttg/process/FrontierManager.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/FrontierManager.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,408 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.test.Debug;
+import com.nailabs.abac.credential.RtmlFrontier;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.engine.*;
+import edu.stanford.peer.rbtm.test.*;
+import edu.stanford.peer.rbtm.util.*;
+
+import java.util.*;
+
+/** 
+ * A manager class for frontier functions. Each set of functions should
+ * be unique to a principal. The manager is a singleton object with a method
+ * for obtaining a set of specific frontiers.
+ */
+public class FrontierManager  extends com.nailabs.abac.test.TestEngine 
+    implements java.io.Serializable {
+
+    /** Singleton reference table for sharing frontiers. */
+    static Hashtable frontiers = new Hashtable(5);
+    
+    /** The principal identifier, which is an Entity name */
+    protected Entity self;
+
+    /**
+     * The configuration hashmap. Section name is key and stringified 
+     * line vectors are the values
+     */
+    protected HashMap conf;
+
+    /** The set of issuer traceable credentials */
+    protected HashSet cSuperI = new HashSet();
+
+    /** The set of subject traceable credentials */
+    protected HashSet cSuperS = new HashSet();
+
+    /** The set of subject traceable <emp>roles</emp> */
+    protected HashSet subjectTraces = new HashSet();
+
+    protected HashSet issuerTracesDef = new HashSet();
+
+    protected HashSet issuerTracesAll = new HashSet();
+
+    /** a search engine which uses the <code>oppo()</code> predicate */
+    protected GraphEngine oppoLocal;
+
+    /** a search engine which uses the <code>oppo()</code> predicate */
+    protected GraphEngine oppoFrontier;
+    
+    /** a search engine which uses the <code>sens()</code> predicate */
+    protected GraphEngine sensFrontier;
+    
+    /** a search engine which uses the <code>simp()</code> predicate */
+    protected GraphEngine simpFrontier;
+    
+    /** the acknowledgement policy for this principal entity */
+    protected AckPolicy ackPolicy;
+
+    /** the access control policy for this principal entity */
+    protected ACPolicy acPolicy;
+
+    /** constructor for subclasses */
+    protected FrontierManager() { }
+    
+    /** default constructor, only used internally */
+    protected FrontierManager(HashMap config) {
+        init(config);
+    }
+    
+    /**
+     * initialization is no longer in constructor, so subclasses can
+     * manipulate the configuration hash map.
+     */
+    protected void init(HashMap config) {
+	//int track = TRACK_ALL;
+
+	// (0) get the configurations entity identifier
+	this.self =(Entity) config.get("EntityID");
+
+	// (1) load acknowledgement(ACK) policy
+	ackPolicy = (AckPolicy)config.get("AckPolicy");
+
+	// (2) load access control (AC) policy 
+	acPolicy = (ACPolicy)config.get("AccessControl");
+
+	// (3) load issuer traceable roles
+	issuerTracesAll = (HashSet)config.get("IssuerTracesAll");
+	issuerTracesDef = (HashSet)config.get("IssuerTracesDef");
+
+	// (4) load subject traceale roles
+	subjectTraces = (HashSet)config.get("SubjectTraceable");
+
+	// (5) construct sensitive roles predicate from the ack policy
+	Sens sens = new Sens(ackPolicy.getSensitiveRoles());
+
+	// (6) construct opponent predicate from the issuer traceable roles
+	Oppo oppo = new Oppo(new Vector(issuerTracesDef));
+	oppo.addSubjects(new Vector(issuerTracesAll));
+
+	// (7) construct the frontier functions with their predicates
+	oppoLocal = new GraphEngine();
+	//System.out.println("------> Sensitive Graph");
+	sensFrontier = new GraphEngine(sens);
+	//System.out.println("------> Opponent Graph");
+	oppoFrontier = new GraphEngine(oppo);
+	//System.out.println("------> Simple Graph");
+	simpFrontier = new GraphEngine(new Simp());
+
+	// TBD: Does this really need to be separated into two mutually exclusive
+	//      credential sets?
+	// (8) add policy reachable credentials
+	System.out.println("------> Policy Reachable");
+	HashSet policyReachable = (HashSet)config.get("PolicyReachable");
+	Iterator ci = policyReachable.iterator();
+	while(ci.hasNext()) {
+	    addPolicyReachable((StaticCredential)ci.next());
+	}
+	 
+	// (9) add self reachable credentials
+	System.out.println("------> Self Traceable");
+	HashSet selfReachable = (HashSet)config.get("SelfReachable");
+	Iterator cs = selfReachable.iterator();
+	while(cs.hasNext()) {
+	    addSelfReachable((StaticCredential)cs.next());
+	}
+
+    }
+    public static void addFrontier(HashMap config) {
+	Entity key = (Entity)config.get("EntityID");
+	boolean hasRTML = config.containsKey("RTML");
+	System.out.println("Begin Configuration for " + key);
+	 if(frontiers.contains(key.toString()))
+	     System.out.println("WARNING overwriting frontier manager for " +
+		 	       key);	
+	 FrontierManager frontier = hasRTML? new RtmlFrontier(config): 
+	    new FrontierManager(config);
+	 frontiers.put(key.toString(), frontier);
+	 System.out.println("End Configuration for " + key);
+    } 
+
+    /** public instance accessor method for a specific frontier set */
+    public static FrontierManager getFrontier(Entity self) {
+        System.out.println("self = " + self);
+        FrontierManager instance = 
+            (FrontierManager)frontiers.get(self.toString());
+        return instance;
+    }
+
+    /** public accessor for a list of instance keys */
+    public static Set getFrontiers() { return frontiers.keySet(); }
+
+    /** the unique identifier for this set of frontier functions */
+    public Entity getSelf() { return self; }
+
+    /** Extract the role name from a role expression (e.g. r from <A.r<--S>) */
+    protected RoleName getRoleName(StaticCredential cred) {
+	return getRoleName(cred.getDefinedRole());
+    }
+
+    /** Extract the role name from a role expression (e.g. r from A.r) */
+    protected RoleName getRoleName(EntityExpression expr) {
+	if(expr != null && (expr instanceof Role)) {
+	    return ((Role)expr).getName();
+	}
+	return null;
+    }
+
+    /** adds an issuer traceable credential to the frontier set */
+    public void addSelfReachable(StaticCredential cred) {
+        if(isSubjectTraceable(getRoleName(cred))) {
+            sensFrontier.addCredential(cred);
+            simpFrontier.addCredential(cred);
+            cSuperS.add(cred);
+        }
+    }
+    
+    /** extracts issuer traceable roles from the credntial */
+    public void addPolicyReachable(StaticCredential cred) {
+        if(isIssuerTraceable(getRoleName(cred))) {
+            oppoFrontier.addCredential(cred);
+	    oppoLocal.addCredential(cred);
+            cSuperI.add(cred);
+        }
+    }
+
+
+    /** adds an issuer-traces-all role to this frontier set */
+    public void addIssuerTracesAll(RoleName role) {
+        issuerTracesAll.add(role);
+    }
+
+    /** adds an issuer-traces-def role to this frontier set */
+    public void addIssuerTracesDef(RoleName role) {
+        issuerTracesDef.add(role);
+    }
+
+    /** adds an subject traceable credential to the frontier set */
+    public void addSubjectTraceable(RoleName role) {
+        subjectTraces.add(role);
+    }
+
+    public ResultEvidenceMap getOppoLocal(EntityExpression expr) {
+	//a specialized backward search for the LinkTTNode
+	Debug.rbtmStart();
+        System.out.println("-------BEGIN-LOCAL-SEARCH------------");
+        ResultEvidenceMap map =  oppoLocal.backwardSearch(expr);
+        System.out.println("-------END-LOCAL-SEARCH--------------");
+        Debug.rbtmStop();
+        return map;
+    }
+
+    /** gets the frontier of policy traceable roles */
+    public ResultEvidenceMap getOppoFrontier(EntityExpression expr) {
+        // retrieve solutions AND evidence here
+        Debug.rbtmStart();
+        System.out.println("-------BEGIN-OPPO-SEARCH------------");
+        ResultEvidenceMap map =  oppoFrontier.backwardSearch(expr);
+        System.out.println("-------END-OPPO-SEARCH--------------");
+        Debug.rbtmStop();
+        return map;
+    }
+    
+    /** gets the frontier of sensitive roles */
+    public ResultEvidenceMap getSensFrontier(EntityExpression expr) {
+        Debug.rbtmStart();
+        System.out.println("-------BEGIN-SENS-SEARCH------------");
+        System.out.println("searching for " + expr);
+        ResultEvidenceMap map = sensFrontier.backwardSearch(expr);
+        System.out.println("map = " + map);
+        System.out.println("--------END-SENS-SEARCH-------------");
+        System.out.flush();
+        Debug.rbtmStop();
+        return map;
+    }
+    
+    /** get the frontier of non-role entity expressions */
+    public ResultEvidenceMap getSimpFrontier(EntityExpression expr) {
+        Debug.rbtmStart();
+        System.out.println("-------BEGIN-SIMP-SEARCH------------");
+        ResultEvidenceMap map = simpFrontier.backwardSearch(expr);
+        System.out.println("--------END-SIMP-SEARCH------------");
+        Debug.rbtmStop();
+        return map;
+    }
+
+    public HashSet getOppoChain(EntityExpression root, EntityExpression leaf) {
+        HashSet results = new HashSet();
+        try {
+            getOppoFrontier(root);
+            Debug.rbtmStart();
+            System.out.println("Getting oppo chain from " + root + " to " + 
+                               leaf);
+            results = oppoFrontier.getChain(root, leaf);
+            Debug.rbtmStop();
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+        Debug.rbtmStop();
+        return results;
+    }
+
+    public HashSet getSensChain(EntityExpression root, EntityExpression leaf) {
+        //if(!getSensFrontier(root).containsResult(leaf)) {
+        //return null; 
+        //}
+        try {
+            getSensFrontier(root);
+            Debug.rbtmStart();
+            System.out.println("---------BEGIN-SENS-CHAIN----------");
+            System.out.println("Getting sens chain from " + root + " to " + 
+                               leaf);
+            HashSet results = sensFrontier.getChain(root, leaf);
+            System.out.println("results = " + results);
+            System.out.println("-----------END-SENS-CHAIN----------\n");
+            Debug.rbtmStop();
+            return results;
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        } 
+        System.out.println("-----------END-SENS-CHAIN----------\n");
+        Debug.rbtmStop();
+        return new HashSet();
+    }
+
+    public HashSet getSimpChain(EntityExpression root, EntityExpression leaf) {
+        System.out.println("Getting simp chain from " + root + " to " + leaf);
+        getSimpFrontier(root);
+        Debug.rbtmStart();
+        HashSet results = simpFrontier.getChain(root, leaf);
+        Debug.rbtmStop();
+        return results;
+    }
+
+    public Iterator getCredentialsDefiningRole(RoleName name) {
+	Iterator i;
+	int count = 0;
+	HashSet results = new HashSet();
+    
+	Debug.rbtmStart();
+	System.out.println("Finding credential defining the role name: "+name);
+	i = oppoFrontier.findCredentialsDefiningRole(name);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	i = sensFrontier.findCredentialsDefiningRole(name);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	Debug.rbtmStop();
+	Debug.debug("process", "\nDefining creds = " + results);
+	return results.iterator();
+    }
+
+    /** accessor for finding credentials which define a specified role */
+    public Iterator getCredentialsDefiningRole(Role role) {
+	Iterator i;
+	int count = 0;
+	HashSet results = new HashSet();
+    
+	Debug.rbtmStart();
+	System.out.println("Finding credential defining the role: <" + 
+			   role.getBase() + "." +  role.getName() + ">" );
+	
+	i = oppoFrontier.findCredentialsDefiningRole(role);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	System.out.println("oppoFrontier = " + oppoFrontier);
+	i = sensFrontier.findCredentialsDefiningRole(role);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	Debug.debug("process", "\nDefining creds = " + results);
+
+	Debug.rbtmStop();
+	return results.iterator();
+    }
+
+    /** Is the specified credential policy traceable? */
+    public boolean isPolicyTraceable(StaticCredential cred) {
+	return cSuperI.contains(cred);
+    }
+
+    /** Can the specified credential be traced back to this negotiator? */
+    public boolean isSelfReachable(StaticCredential cred) {
+	return cSuperS.contains(cred);
+    }
+
+    public boolean isSubjectTraceable(RoleName role) {
+	return subjectTraces.contains(role);
+    }
+
+    public boolean isIssuerTracesDef(RoleName name) {
+        return (issuerTracesDef.contains(name));
+    }
+
+    public boolean isIssuerTracesAll(RoleName name) {
+        return (issuerTracesAll.contains(name));
+    }
+
+    public boolean isIssuerTraceable(RoleName role) {
+    return (issuerTracesAll.contains(role) || issuerTracesDef.contains(role));
+    }
+
+    public boolean isSensitive(EntityExpression expr) {
+	return sensFrontier.getPredicate().test(expr);
+    }
+    
+    public boolean subjectTracesAll(RoleName name) {
+	return subjectTraces.contains(name);
+    }
+
+    public AckPolicy getAckPolicy() { return ackPolicy; }
+
+    public EntityExpression getAck(EntityExpression expr) {
+	return ackPolicy.requires(expr);
+    }
+    
+    public ACPolicy getACPolicy() { return acPolicy; }
+
+    public EntityExpression getAC(Credential cred) {
+	if(acPolicy == null)return null;
+	return acPolicy.requires(cred);
+    }
+
+    protected void addSensitiveRole(Role name) {
+	Sens sens = (Sens)sensFrontier.getPredicate();
+	sens.addSensCred(name);
+    }
+
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[FrontierManager self = ");
+	buff.append(self);
+	buff.append("\n sens = ").append(sensFrontier);
+	buff.append("\n\n oppo = ").append(oppoFrontier);
+	buff.append("\n\n simp = ").append(simpFrontier);
+	return buff.append("]").toString();
+    }
+
+}
+
+
+
Index: fedd/abac-src/ttg/process/ImplicationEdge.java
===================================================================
--- fedd/abac-src/ttg/process/ImplicationEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/ImplicationEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,88 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import java.util.*;
+
+/**
+ * An implication edge represents an edge in a trust target graph 
+ * (<CODE>TTG</CODE>) with accompanying evidence. An implication edge 
+ * is proved by a set of credentials (i.e. a chain).
+ */
+public class ImplicationEdge extends EdgeOperation {
+    
+    /** Jared: Added this method to make XML processing easier */
+    public ImplicationEdge() {
+        super();
+        type = new String("Implication");
+    }
+    
+    /** 
+     * Default constructor 
+     * @param parent an upcast StandardTTNode
+     * @param child an upcast TargetNode
+     */
+    public ImplicationEdge(Goal parent, Goal child, ProcessingState state,
+			   HashSet evidence) {
+	super(parent, child, state, evidence);
+	type = new String("Implication");
+	debug("edge", "state = " + state );
+    }
+
+    public void performAdditional(TTG graph) {
+	StandardTTNode parent=(StandardTTNode)graph.getNodeByHash(getParent());
+	TargetNode child = (TargetNode)graph.getNode(getChild());
+	debug("perform", "performing " + toString(parent, child));
+	parent.addImplicationChild(child);
+	child.addImplicationParent(parent);
+	//propagate satisfaction for all nodes
+	int satisfaction = child.getSatisfactionValue();
+	debug("perform",  "child is satified =  " + 
+			   (satisfaction == SatisfactionState.SATISFIED));
+	//if(child instanceof TrivialTTNode)
+	//parent.receive((TrustTarget)child.getGoal(),
+	//new SatisfactionState(satisfaction)); 
+    }
+
+    public void performNewAdditional(TTG graph) {
+	TTGNode child = graph.getNodeByHash(getChild());
+	if(child == null) {
+	    child = TTGNode.createNode(getChild());
+	    debug("newop", performNewInfo());
+	    // set processing if necessary here
+	    if(state != null) {
+		child.getProcessingState().update(state);
+	    } else {
+		debug("newop", "warning perform new additional has no state");
+	    }
+	    graph.putNodeByHash(child);
+	}
+	performAdditional(graph);
+    }
+    
+    /** Friendly debugging convenience method */
+    protected void debug(String level, String message) {
+	StringBuffer buff = new StringBuffer("ImplicationEdge: ");
+	buff.append(message);
+	Debug.debug(level, buff.toString());
+    }
+
+
+    public String toString(StandardTTNode parent, TargetNode child) {
+	StringBuffer buff = new StringBuffer("[ImplicationEdge  ");
+	buff.append(parent).append(" <<=== ");
+	buff.append(child);
+	return buff.toString();
+    }
+
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[ImplicationEdge  ");
+	buff.append(getParent()).append(" <<=== ");
+	buff.append(getChild()).append(", state = ");
+	buff.append(state).append(", evidence = ");
+    buff.append(getEvidence());
+	return buff.toString();
+    }
+
+}
+
Index: fedd/abac-src/ttg/process/IntersectionEdge.java
===================================================================
--- fedd/abac-src/ttg/process/IntersectionEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/IntersectionEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,50 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+
+public class IntersectionEdge extends EdgeOperation {
+    
+    /** Jared: Added this method to make XML processing easier */
+    public IntersectionEdge() {
+        super();
+        type = new String("Intersection");
+    }
+
+    public IntersectionEdge(Goal parent, Goal child, ProcessingState state) {
+        super(parent, child, state, null);
+        //TBD: add extra type checking--verify child is a part of the and-ing
+        type = new String("Intersection");
+        Debug.debug("intersection", toString());
+    }
+
+    public void performAdditional(TTG graph) {
+        IntersectionTTNode parent = 
+            (IntersectionTTNode)graph.getNodeByHash(getParent());
+        TargetNode child = (TargetNode)graph.getNodeByHash(getChild());
+
+        parent.addIntersectionChild(child);
+        child.addImplicationParent(parent);
+    }
+    
+    public void performNewAdditional(TTG graph) {
+        TargetNode child = (TargetNode)graph.getNodeByHash(getChild());
+        if(child == null) {
+            Debug.debug("intersection", "child = " + child);
+            child = (TargetNode)TTGNode.createNode(getChild());
+            child.getProcessingState().update(state);
+            graph.putNodeByHash(child);
+        }
+        performAdditional(graph); 
+    }
+
+    public String toString() {
+        StringBuffer buff = new StringBuffer("[");
+        buff.append(type).append("Edge ");
+        buff.append(getParent()).append(" <<=== ");
+        buff.append(getChild()).append(", state = ");
+        buff.append(state).append("]");
+        return buff.toString();
+    }
+
+}
Index: fedd/abac-src/ttg/process/LinkingImplicationEdge.java
===================================================================
--- fedd/abac-src/ttg/process/LinkingImplicationEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/LinkingImplicationEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,37 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import java.util.*;
+
+/**
+ * A linking implication edge represents an edge in a trust target graph 
+ * between a <CODE>LinkTTNode</CODE> and a <CODE>SimpleTTNode</CODE>
+ */
+public class LinkingImplicationEdge extends ImplicationEdge {
+    /** default constructor (used for TNT integration) */
+    public LinkingImplicationEdge() {
+        super();
+        type = new String("LinkingImplication");
+    }
+
+    /** parsed elements contructor */
+    public LinkingImplicationEdge(TrustTarget parent, TrustTarget child, 
+                                  ProcessingState state) {
+        super(parent, child, state, null);
+        type = "LinkingImplication";
+    }
+    
+    /** convert this edge into a human-readable formatted String */
+    public String toString() {
+        StringBuffer buff = new StringBuffer("[");
+        buff.append(type).append("Edge");
+        buff.append(getParent()).append(" <<=== ");
+        buff.append(getChild()).append(", state = ");
+        buff.append(state).append("]");
+        return buff.toString();
+    }
+
+}
+
+
Index: fedd/abac-src/ttg/process/LinkingMonitorEdge.java
===================================================================
--- fedd/abac-src/ttg/process/LinkingMonitorEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/LinkingMonitorEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,50 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import java.util.*;
+
+/**
+ * A linking implication edge represents an edge in a trust target graph 
+ * between a <CODE>LinkTTNode</CODE> and a <CODE>LinkingGoalNode</CODE>
+ */
+public class LinkingMonitorEdge extends EdgeOperation {
+    /** Default constructor (used for TNT integration).*/  
+    public LinkingMonitorEdge() {
+        super();
+        type = new String("LinkingMonitor");
+    }
+    
+    /** Parsed element constructor */ 
+    public LinkingMonitorEdge(TrustTarget parent, LinkingGoal child, 
+                              ProcessingState state) {
+        super(parent, child, state, null);
+        type = "LinkingMonitor";
+    }
+    
+    public void performAdditional(TTG graph) {
+        LinkTTNode parent = (LinkTTNode)graph.getNodeByHash(getParent());
+        LinkingGoalNode child = 
+            (LinkingGoalNode)graph.getNodeByHash(getChild());
+
+        parent.addChild(child);
+        child.addParent(parent);
+    }
+    
+    public void performNewAdditional(TTG graph) {
+        LinkingGoalNode child = 
+            (LinkingGoalNode)graph.getNodeByHash(getChild());
+        if(child == null) {
+            child = (LinkingGoalNode)TTGNode.createNode(getChild());
+            child.getProcessingState().update(state);
+            graph.putNodeByHash(child);
+        }
+        performAdditional(graph); 
+    }
+
+}
+
+
+
+
+
Index: fedd/abac-src/ttg/process/LinkingSolutionEdge.java
===================================================================
--- fedd/abac-src/ttg/process/LinkingSolutionEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/LinkingSolutionEdge.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,49 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import java.util.*;
+
+/**
+ * A linking soilution edge represents an edge in a trust target graph 
+ * between a <CODE>LinkingGoalNode</CODE> and it's solution children.
+ */
+public class LinkingSolutionEdge extends EdgeOperation {
+    /** Default constructor */   
+    public LinkingSolutionEdge() {
+        super();
+        type = new String("LinkingSolution");
+    }
+
+    /** Parsed element constructor */
+    public LinkingSolutionEdge(LinkingGoal parent, TrustTarget child, 
+                              ProcessingState state) {
+        super(parent, child, state, null);
+        type = "LinkingSolution";
+    }
+    
+    public void performAdditional(TTG graph) {
+        SimpleTTNode child = (SimpleTTNode)graph.getNodeByHash(getChild());
+        LinkingGoalNode parent = 
+            (LinkingGoalNode)graph.getNodeByHash(getParent());
+
+        parent.addChild(child);
+        child.addLinkingSolutionParent(parent);
+    }
+    
+    public void performNewAdditional(TTG graph) {
+        TargetNode child = (TargetNode)graph.getNodeByHash(getChild());
+        if(child == null) {
+            child = (TargetNode)TTGNode.createNode(getChild());
+            child.getProcessingState().update(state);
+            graph.putNodeByHash(child);
+        }
+        performAdditional(graph); 
+    }
+
+}
+
+
+
+
+
Index: fedd/abac-src/ttg/process/Message.java
===================================================================
--- fedd/abac-src/ttg/process/Message.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/Message.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,130 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.credential.RtmlCredential;
+
+import com.nailabs.abac.test.*;
+import java.io.*;
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+
+/**
+ * A message contains a set of operations to be transmitted between two 
+ * negotiators.
+ */
+public class Message implements Serializable, XMLizable {
+    /** A history list of operations */
+    private LinkedList ops;
+
+    private transient Iterator opsIterator = null;
+
+    /** Credentials used for proving edge operations. */ 
+    private HashSet evidence;
+
+    /** Default contructor for a message instance. */
+    public Message() {
+	ops = new LinkedList();
+	evidence = new HashSet(10);
+    }
+
+    /** Public accessor method for iterating over operations in the message */
+    public Iterator getOperations() { return ops.iterator(); }
+
+    /** Accessor method for the graph delta queue. */
+    public Operation getNextOperation() { 
+	if(opsIterator == null)
+	    opsIterator = ops.iterator();
+	return (Operation)opsIterator.next(); 
+    }
+
+    /** Adds an operation that contains internal evidence. */
+    public synchronized void addOperationWithoutEvidence(Operation op) {
+        ops.add(op);
+    }
+
+    /** Add and operation to end of the operations queue */
+    public synchronized void addOperation(Operation op) {
+        ops.add(op);
+        //add the evidence
+        if(op instanceof EdgeOperation) {
+            HashSet subEvidence = ((EdgeOperation)op).getEvidence();
+            if(subEvidence == null) {
+                //Debug.debug("message", "Message: No evidence available..."); 
+                return;
+            }
+            Iterator i = subEvidence.iterator();
+            while(i.hasNext()) {
+                Object proof = i.next();
+                evidence.add(proof);
+            }
+        }
+    }
+
+    /** Message count of operations in this message. */
+    public int getOperationsCount() { 
+        return (ops == null)? 0: ops.size();
+    }
+
+    /** Accessor method for the combined evidence. */
+    public Iterator  getEvidence() { return evidence.iterator(); }
+
+    /** Evidence (credentials) count. Convenience method for Iterator */
+    public int getEvidenceCount() { 
+	return (evidence == null)? 0: evidence.size();
+    }
+    
+    /** Add a new credential to the list of evidence. */
+ public synchronized void addEvidence(Credential cred) {
+        if(cred instanceof RtmlCredential) {
+            evidence.add(((RtmlCredential)cred).toXML());
+        } else {
+	    evidence.add((Object)cred);
+	}
+    }
+
+    /** Converts this message instance into an XML formatted string */
+    public String toXML() {
+	StringBuffer buff = new 
+	    StringBuffer("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
+        buff.append("<Message xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://isrl.cs.byu.edu/xsd/message.xsd\">\n");
+	Iterator creds = evidence.iterator();
+	if(creds.hasNext()) {
+	    int count = 0;
+	    buff.append("<Evidence>\n");
+	    while(creds.hasNext()) {
+		Object cred = creds.next();
+		buff.append("<!-- credential count = ").append(++count);
+		buff.append(" -->\n");
+		if(cred instanceof RtmlCredential)
+		    buff.append(((RtmlCredential)cred).toXML()).append("\n");
+		else 
+		    buff.append(cred.toString()).append("\n");
+	    }
+	    buff.append("</Evidence>\n");
+	}
+	ListIterator i = ops.listIterator();
+	int n = 0;
+	while(i.hasNext()) {
+	    Operation op = (Operation)i.next();
+	    buff.append("<!--Operation no. ").append(++n).append("-->\n");
+	    buff.append(op.toXML());
+	}
+	return buff.append("</Message>\n").toString();
+    }
+
+    /** Prints out this message in human readable format */
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[Message ");
+	int n = 0;
+	ListIterator i = ops.listIterator();
+
+	while(i.hasNext()) {
+	    buff.append("\n\t(").append(++n).append(") ");
+	    buff.append(i.next());
+	}
+	buff.append("\n").append(ops.size()).append(" operations total");
+    buff.append("\n evidence: ");
+    buff.append(evidence.toString());
+	return buff.append("]").toString();
+    }
+    
+}
Index: fedd/abac-src/ttg/process/NegotiationContext.java
===================================================================
--- fedd/abac-src/ttg/process/NegotiationContext.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/NegotiationContext.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,99 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.engine.*;
+
+import java.util.*;
+
+/**
+ * A negotiation context contains all the objects necessary for performing
+ * a trust negotiation transaction.
+ */
+public class NegotiationContext {
+
+    // The frontiers for self are static in a context.
+
+    /** This a shared data structure for accessing a principal's credentials */
+    protected FrontierManager frontier;
+
+    /** The strategy for processing nodes in this negotiation. */
+    protected Strategy strategy;
+
+    /** The trust target graph used to store the nodes */
+    protected TTG trustGraph;
+
+    /** The remote negotiator in a two party negotiation */
+    protected Entity oppo;
+    
+    /** Credentials received from the opponent negotiator */
+    protected GraphEngine oppoCred;
+    
+    /** Observer for logging ttg information */
+    protected PropertiesObserver observer;
+
+    /** Construct a new context for a specific negotiation */
+    public NegotiationContext(HashMap mediationInfo) {
+        Entity self = (Entity)mediationInfo.get("EntityID");
+        Entity peer = (Entity)mediationInfo.get("Peer");
+        mediationInfo.put("context", this);
+        frontier = FrontierManager.getFrontier(self);
+        oppo = peer;
+        observer = new PropertiesObserver(self);
+        trustGraph = new TTG(this);
+        trustGraph.addObserver(observer);
+        strategy = StrategyFactory.getStrategy(mediationInfo);
+        strategy.addObserver(observer);
+    }
+
+    /** public accessor method for the trust target graph */
+    public TTG getGraph() { return trustGraph; }
+
+    /** public accessor mehotd for the processing instance */
+    public Strategy getStrategy() { return strategy; }
+
+    /** public accessor method for the opponent */
+    public Entity getOpponent() { return oppo; }
+
+    /** public accessor method for the frontier functions */
+    public FrontierManager getFrontier() { return frontier; }
+
+    /** public accessor method for the local negotiator's identity */
+    public Entity getSelf() { return frontier.getSelf(); }
+
+    /** adds a list of credentials from the opponent */
+    public void addCredentials(LinkedList otherCreds) {
+	oppoCred.addCredentials(otherCreds);
+    }
+    
+    /** Is the given credential a member of cS */
+    public boolean isTraceable(StaticCredential cred) {
+	return frontier.isSelfReachable(cred);
+    }
+
+    public boolean subjectTracesAll(RoleName name) {
+	return frontier.subjectTracesAll(name);
+    }
+
+    /** lookup method for Ack policy */
+    public EntityExpression getAck(EntityExpression e) {
+	return frontier.getAck(e);
+    }
+
+    /** lookup method for AC policy */
+    public EntityExpression getAC(Credential cred) {
+	return frontier.getAC(cred);
+    }
+
+
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[NegotiationContext ");
+	buff.append(frontier).append(", ");
+	buff.append(trustGraph).append(", ");	
+	buff.append(strategy).append("]");
+	return(buff.toString());
+    }
+
+}
+
Index: fedd/abac-src/ttg/process/Negotiator.java
===================================================================
--- fedd/abac-src/ttg/process/Negotiator.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/Negotiator.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,42 @@
+package com.nailabs.abac.process;
+
+import edu.stanford.peer.rbtm.credential.Entity;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * The negotiator interface is responsible for sending and receiving messages.
+ * In this class, the term opponent is used to describe the other negotiatior,
+ * not necessarily the opponent, O, described in the processing algorithms.
+ */
+public interface Negotiator extends Remote {
+    /** 
+     * Synchronously receive a message which can contain multiple operations 
+     * from an opponent and then return the updates to the originating 
+     * opponent.
+     */
+    public abstract Message receive(Message msg) 
+        throws Exception, RemoteException;
+
+    /**
+     * Method to invoke a negotiation.
+     */
+    public abstract boolean negotiate() throws RemoteException;
+
+    /**
+     * Accessor method for getting the identity of whose behalf the peer
+     * negotiator is working.
+     */
+    public abstract Entity getSelf()throws RemoteException;
+
+    /**
+     * Asynchronous method to transmit a message to the opponent. 
+     */
+    //public abstract void transmit(Message msg);
+
+    /**
+     * Asynchronous method to receive a method from the opponent.
+     */
+    //public abstract void receive(Message msg);
+
+}
Index: fedd/abac-src/ttg/process/NodeOperation.java
===================================================================
--- fedd/abac-src/ttg/process/NodeOperation.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/NodeOperation.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,119 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+
+/**
+ * This is a specialized operation for transmitting a root node between
+ * negotiators.
+ */
+public class NodeOperation implements Operation {
+    /** The new node to construct */
+    Goal goal;
+
+    /** An optional processing state */
+    ProcessingState state;
+
+    /** a flag to denote whether this is a new (i.e. root) node or not */
+    boolean isRoot = false;
+
+    /** root node operation constructor */
+    public NodeOperation(Goal g, ProcessingState ps, boolean isRoot) {
+	goal = g;
+	state = ps;
+	this.isRoot = isRoot;
+    }
+
+    /** non-root, node state change operation */
+    public NodeOperation(Goal g, ProcessingState ps) {
+	goal = g;
+	state = ps;
+	isRoot = false;
+    }
+    
+    /** Jared: Added this method to make XML processing easier */
+    public NodeOperation() {
+        goal = null;
+        state = null;
+    }
+    
+    /** Jared: Added this method to make XML processing easier */
+    public void setGoal(Goal g) { goal = g; }
+    
+    /** Jared: Added this method to make XML processing easier */
+    public void setProcessingState(ProcessingState ps) { state = ps; }
+    
+    /** Jared: Added this method to make XML processing easier */
+    public void setRoot(boolean isRoot) { this.isRoot = isRoot; }
+
+    /** public accessor method used for logging this node's goal */
+    public Goal getGoal() { return goal; }
+
+    /** public accessor method for determinig whether this is a root node */
+    public boolean isRoot() { return isRoot; }
+
+    /** public accessor method for finding the updated processing state */
+    public ProcessingState getProcessingState() { return state; }
+
+    /** 
+     * Either add a new node to the root of the trust target graph or
+     * update the processing state of an existing node.
+     */
+    public void perform(TTG graph) {
+	StringBuffer buff;
+	if(isRoot) {
+	    buff = new StringBuffer("adding root node ");
+	    buff.append(goal).append(" to ").append(graph);
+	    debug("root", buff.toString());
+	    graph.putRoot((TargetNode)graph.getNode((TrustTarget)goal));
+ 	}
+	buff = new StringBuffer("updating node ");
+	buff.append(goal).append(" with ").append(state);
+	debug("node", buff.toString());
+	TTGNode node = graph.getNodeByHash(goal);
+	//node.getProcessingState().update(state);
+    node.updateProcessingState(state);
+    }
+
+    /** Friendly debugging convenience method */
+    protected void debug(String level, String message) {
+	StringBuffer buff = new StringBuffer("NodeOperation:");
+	buff.append(message);
+	Debug.debug(level, buff.toString());
+    }
+
+    public String toXML() {
+	StringBuffer buff =  new StringBuffer("<NodeOperation");
+	if(isRoot) {
+	    buff.append(" type=\"root\">\n");
+	} else {
+	    buff.append(">\n");
+	}
+        buff.append("<TrustTarget>");
+	buff.append(goal.toXML());
+        buff.append("</TrustTarget>\n");
+	buff.append(state.toXML());
+	buff.append("</NodeOperation>\n");
+	return buff.toString();
+    }
+
+
+    /** Converts this operation into a string */
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[NodeOperation ");
+	if(isRoot){
+	    buff.append("root = ").append(goal);
+	    if(state != null) {
+		buff.append(", processing state = ").append(state);
+	    }
+	}
+	else {
+	    buff.append("node = ").append(goal);
+	    buff.append(", processing state = ").append(state);
+	}
+	buff.append("]");
+	return buff.toString();
+    }
+
+}
+
Index: fedd/abac-src/ttg/process/Operation.java
===================================================================
--- fedd/abac-src/ttg/process/Operation.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/Operation.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,18 @@
+package com.nailabs.abac.process;
+
+import java.io.*;
+import com.nailabs.abac.test.*;
+
+/**
+ * Operations are performed on trust target graph objects. Operations are 
+ * generally edge operations (between nodes in a trust target graph, but
+ * there is one node operation for creating a root node.
+ */
+public interface Operation extends Serializable, XMLizable{
+    /** Execute the operation on the specified trust target graph. */ 
+    public void perform(TTG graph);
+
+    /** Convert this operation into an XML compatible format */
+    public String toXML();
+}
+
Index: fedd/abac-src/ttg/process/RMINegotiator.java
===================================================================
--- fedd/abac-src/ttg/process/RMINegotiator.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/RMINegotiator.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,135 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import edu.stanford.peer.rbtm.credential.Entity;
+import java.rmi.*;
+import java.rmi.server.*;
+
+/**
+ * This class is a concrete negotiator implementation that employs RMI as the
+ * underlying communications transport mechanism.
+ */
+public class RMINegotiator extends UnicastRemoteObject implements Negotiator  {
+    /**
+     * The peer with which this instance negotiates.
+     */
+    protected Negotiator peer;
+
+    /** 
+     * The context for the current negotiation, including a trust target graph,
+     * strategy, and frontier manager instances.
+     */
+    protected NegotiationContext context;
+
+    /**
+     * Default constructor for the client-side negotiatior. This negotiator
+     * is requesting access to a resource.
+     */
+    public RMINegotiator(NegotiationContext nc) throws RemoteException { 
+	context = nc;
+    }
+
+    /**
+     * Constructor for the server-side negotiator. This negotiator has a 
+     * resource that needs protection. 
+     */
+    public RMINegotiator(TargetNode root, RMINegotiator peer) 
+        throws RemoteException {
+        setPeer(peer); 
+    } 
+    
+    public Entity getSelf() 
+    {
+        return context.getSelf();
+    }
+
+    /**
+     * initial a new root node and start the negotiation process. 
+     */
+    public boolean negotiate() {
+	TTG graph = context.getGraph();
+	Strategy s = context.getStrategy();
+	SatisfactionState state;
+	int i = 0;
+	debug("pre-processing locally...");
+	//perform strategy once
+	s.iterate();
+	Message changes = graph.getChanges();
+	graph.reset();
+	do {
+	    debug("processing cycle = " + ++i);
+	    debug("sending message " + changes);
+            System.out.println("Sending message: ");
+            System.out.println(changes.toXML());
+        try {
+            Message updates = peer.receive(changes);
+            debug("receiving message " + updates);
+            changes = receive(updates);
+        }
+        catch(Exception ex) {
+            Debug.rbtmStop();
+            ex.printStackTrace();
+            return false;
+        }
+	    state = new SatisfactionState(context.getStrategy().getSatisfactionState());
+	    debug("RMINegotiator:  primary trust target  is " + state);
+	}while(state.getState() == SatisfactionState.UNKNOWN && i <= 100);
+	// out of the loop so we need to return success or failure
+	return (state.getState() == SatisfactionState.SATISFIED);
+    }
+
+
+    /** set the other negotiator dynamically */
+    public void setPeer(Negotiator peer) {
+	this.peer = peer;
+    }
+
+    public void setRoot(TrustTarget tt) {
+	context.getGraph().setRoot(tt);
+	//TargetNode node = (TargetNode)context.getGraph().getNodeByHash(tt);
+	//context.getStrategy().addToWorklist(node);
+    }
+    
+
+    /** 
+     * Synchronously receive a message which can contain multiple operations 
+     * from an peer and then return the updates to the originating 
+     * peer.
+     */
+    public Message receive(Message msg) throws Exception {
+	Strategy strategy = context.getStrategy();
+	TTG graph = context.getGraph();
+	Message results = null;
+
+	//for(int i = 0, max = msg.getOperationsCount(); i < max; i++) {
+	//    System.out.println("max = " + max);
+	//   try {
+	//	Operation op = msg.getNextOperation();
+	//	op.perform(graph);
+	//    }
+	//    catch(Exception ex) {
+	//	ex.printStackTrace();
+	//    }
+	//}
+	debug("begin receive");
+	graph.update(msg);
+	debug("graph has been updated");
+	strategy.process(msg);
+	debug("strategy has processed the work list");
+	results = graph.getChanges();
+	debug("grabbing the delta list = " + results);
+	graph.reset();
+
+	debug("end receive");	
+	return results;
+    }
+    
+    /** convenience method for printing messages */
+    public void debug(String message) {
+	StringBuffer buff = new StringBuffer("RMINegotiator[");
+	buff.append(context.getSelf()).append("]: ").append(message);
+	//System.out.println(buff);
+	Debug.debug("negotiate", buff.toString());
+    }
+}
Index: fedd/abac-src/ttg/process/ResourcePolicy.java
===================================================================
--- fedd/abac-src/ttg/process/ResourcePolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/ResourcePolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,62 @@
+package com.nailabs.abac.process;
+
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+//import edu.stanford.peer.rbtm.engine.StaticCredential;
+
+/**
+ * Resource policy for negotiations. The policy can be queried using the 
+ * <code>requires</code> method with a specific credential resource 
+ * identifier, which can be a URl or a mnemonic identifier.
+ */
+public class ResourcePolicy implements java.io.Serializable {
+    /** Internal hash table for policy storage */
+    private HashMap resourcePolicy = null;
+
+    /** Default constructor with a non-resstrictive policy */
+    public ResourcePolicy() {
+	resourcePolicy = new HashMap();
+    }
+
+    /** Accessor for all the access control policy keys */
+    public Vector getResourceIdentifiers() { 
+        return new Vector(resourcePolicy.keySet()); 
+    }
+
+    /** 
+     * Useful for forward discovery. 
+     * @return a set of all roles which satisfy the AC policy requirements
+     */
+    public Vector getRequiredRoles() {
+	return new Vector(resourcePolicy.values());
+    }
+
+    /** Adds a single policy atom from String parameters. */
+    public void addResourceFact(String resourceID, String role) 
+	throws CredentialParsingException {
+	try {
+	    addResourceFact(resourceID, (Role)StaticCredential.getRole(role));
+	} catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+    }
+
+    /** Adds a single policy atom. */
+    public void addResourceFact(String key, Role role) {
+	resourcePolicy.put(key, role);
+    }
+
+    /** Query the policy to determine the required role for a credential */
+    public Role requires(String resource) {
+	return (Role)resourcePolicy.get(resource);
+    }
+
+    /** Returns the underlying storage data structure in a printable format */
+    public String toString() {
+	if(resourcePolicy == null)
+	    return null;
+	else 
+	    return resourcePolicy.toString();
+    }
+
+}
Index: fedd/abac-src/ttg/process/SatisfactionListener.java
===================================================================
--- fedd/abac-src/ttg/process/SatisfactionListener.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/SatisfactionListener.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,12 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+
+/** 
+ * An interface implemented by any class which needs to propagate 
+ * satisfaction state within the context of a trust target graph.
+ */
+public interface SatisfactionListener {
+    /** The method for propagating satisfaction state. */
+    public TTGNodeSet receive(TrustTarget target, SatisfactionState state);
+}
Index: fedd/abac-src/ttg/process/StingyStrategy.java
===================================================================
--- fedd/abac-src/ttg/process/StingyStrategy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/StingyStrategy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,327 @@
+package com.nailabs.abac.process;
+
+import edu.stanford.peer.rbtm.credential.*;
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import java.util.*;
+/**
+ * The strategy handles processing a working list of nodes in the trust target
+ * graph to be processed. This version uses a combination of heuristics with 
+ * a depth first search method.
+ */
+public class StingyStrategy extends Strategy {
+    /** A queue for operations which need to delay */
+    protected Hashtable delayedOps = new Hashtable();
+    
+    /** 
+     * A list of sibling children of the current node being processed. Note,
+     * this is an ordered stack. Node operations are added the bottom of the
+     * stack and implication edges are added to the top. 
+     */
+    protected Vector siblings = new Vector();
+
+    /** The current node being processed. Null if no local processing. */
+    protected TTGNode current = null;
+    
+    /** Is this strategy currently processing locally? */
+    protected boolean isLocal = false;
+
+    /** 
+     * A threshold for determining when isDone is high enough 
+     */
+    public int threshold = 0;
+
+    public float successWeight = 0.0f;
+
+    public CountTable weights = null;
+
+    /** A count of how many criteria have been met for ending a turn */
+    protected int isDone = 0;
+
+    /** Check to see if  already saved weights, which should only occur once */
+    private boolean isSaved = false;
+
+    /** create a new stingy strategy instance */
+    public StingyStrategy(NegotiationContext conf, Properties props) {
+        super(conf);
+        try {
+            if(props.containsKey("successWeight")) {
+                successWeight = 
+                Float.parseFloat(props.getProperty("successWeight"));
+            }
+            if(props.containsKey("weightFile")) {
+                weights = new CountTable(props.getProperty("weightFile"));
+            } else {
+                weights = new CountTable("weights." + context.getSelf());
+            }
+            if(props.containsKey("init")) {
+                weights.INIT = 
+                    Float.parseFloat(props.getProperty("init"));
+            }
+            if(props.containsKey("sat")) {
+                weights.SAT = 
+                    Float.parseFloat(props.getProperty("sat"));
+            }
+            if(props.containsKey("training")) {
+                if(props.getProperty("training").equalsIgnoreCase("true")) {
+                    isSaved = false;
+                } else {
+                    isSaved = true;
+                }
+            }
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * The stingy strategy needs to save weights when the primary trust target
+     * is satisfied. This is method tests the predicate and saves the weight
+     * states as a side effect.
+     */
+    public int getSatisfactionState() {
+        int state = super.getSatisfactionState();
+        if(state == SatisfactionState.UNKNOWN) {
+            return state;
+        }
+        if(isSaved) {
+            return state;
+        }  
+        isSaved = true;
+        Iterator i = context.getGraph().getNodes();
+        while(i.hasNext()) {
+            TTGNode node = (TTGNode)i.next();
+            EntityExpression expr = getWeightKey(node.getGoal());
+            if(node instanceof TargetNode) {
+                state = ((TargetNode)node).getSatisfactionValue();
+            } else {
+                continue;
+            }
+            if(state == SatisfactionState.SATISFIED) { // increment success
+                weights.addSatisfied(expr);
+            } else {
+                //if(state == SatisfactionState.FAILED) {    
+                //increment failure or unkown nodes
+                weights.addFailed(expr);
+            }
+        }
+        debug("strategy", "Saving weights for " + context.getSelf());
+        weights.save("weights." + context.getSelf());    
+        return state;
+    }
+    
+    /** 
+     * Notify the strategy that a new edge needs to be added to the graph.
+     * The strategy is responsible for performing the operation on the graph,
+     * whether the strategy chooses to  defer the operation or not.
+     */
+    public void scheduleOperation(Operation op) {
+        if(!isLocal) {          // process remote operations directly
+            super.scheduleOperation(op);
+            return;
+        }
+        if(op instanceof NodeOperation) { // add node op to end of vector
+            siblings.add(op);
+        } else if(op instanceof ImplicationEdge) { // add  to front of vector
+            //linking implication edges should be performed NOW
+            if(op instanceof LinkingImplicationEdge) { 
+                super.scheduleOperation(op);
+                siblings.remove(op);
+            } else {
+                siblings.add(0, op);
+            }
+        } else {                // perform the operation immediately
+            super.scheduleOperation(op); 
+            siblings.remove(op);
+        }
+    }
+
+    /** Notify this strategy that a control child has been satisfied */
+    public void addSatisfiedControlChild(TTGNode node) {
+        Goal g = (Goal)node.getGoal();
+        Entity v = g.getVerifier();
+        if(!context.getSelf().equals(v)) {
+            //weights.addSatisfied(getWeightKey(g));
+            isDone++;
+        }
+    }
+
+    /** Notify this strategy that a new node has been added to the graph */
+    public void addNewNode(TTGNode node) {
+        if(!isLocal)return;
+        ProcessingState state = node.getProcessingState();
+        Entity v = node.getGoal().getVerifier();
+        if(context.getSelf().equals(v) && state.isVerifierProcessed()) {
+            //increment the isDone counter
+            isDone++;
+        }
+        debug("strategy", "node  = " + node.getGoal());
+        debug("strategy", "isDone = " + isDone);
+    }
+
+    /** iterate through the work list until it is empty */
+    public void iterate() {
+        isDone = 0;
+        while(true) {
+            debug("strategy", "beginning iteratiion");
+            super.iterate();
+            if(okToEndTurn()) {
+                debug("strategy", "ending turning now!");
+                return;
+            }
+            debug("strategy", "processing the delayed queue");
+            processDelayedOps();
+        }
+    }
+
+    /** utility function for getting the target expression out of a goal */
+    protected EntityExpression getWeightKey(Goal g) {
+        EntityExpression key = null;
+        if(g instanceof LinkingGoal) {
+            String roleName = 
+                ((LinkingGoal)g).getTargetRoleName().toString();
+            key = new Role("?X", roleName);
+        }
+        if(g instanceof TrustTarget) {
+            key = ((TrustTarget)g).getTargetRole();
+        }
+        return key;
+    }
+
+    /** Note the beginning of a new parent node being processed */
+    protected void setCurrentParent(TTGNode parent) {
+        //initialize the state variables
+        siblings = new Vector();
+        current = parent;
+        isLocal = true;
+        //isDone = 0;
+    }
+
+    /** Process all the nodes in the delayed queue */
+    protected void processDelayedOps() {
+        Iterator i = delayedOps.values().iterator();
+        while(i.hasNext()) {
+            Vector s = (Vector)i.next();
+            while(!s.isEmpty()) {
+                debug("strategy", "performing delayed op = " + s.get(0)); 
+                super.scheduleOperation((Operation)s.remove(0));
+            }
+            i.remove();
+        }
+    }
+
+    /** Note the conclusion of a new parent node being processed */
+    protected void scheduleOperationsForNode(TTGNode parent) {
+        Entity v = parent.getVerifier();
+        int doCount = 0;
+
+        // if self is not parent's verifier, perform all the operations now
+        if(!context.getSelf().equals(v)) {
+            while(!siblings.isEmpty()) {
+                super.scheduleOperation((Operation)siblings.remove(0));
+            }
+            current = null;
+            isLocal = false;
+            return;
+        }
+        // If the verifier finds itself processing a node it has already 
+        // processed, it will not add any more operations on that node
+        // (this node has been fully processed; therefore, the delayed 
+        //  operations can be ignored.)
+        if(delayedOps.containsKey(current.getGoal())) {
+            debug("strategy", "Already processed node " + current.getGoal());
+            debug("strategy", "siblings = " + siblings);
+            siblings = new Vector(); // potential memory leak--should be gc'ed
+            current = null;
+            isLocal = false;
+            return;
+        }
+        //otherwise perform at least one child
+        Iterator i = siblings.iterator();
+        while(i.hasNext()) {
+            Operation op = (Operation)i.next();
+
+            if(op instanceof ImplicationEdge) {
+                Goal g = ((EdgeOperation)op).getChild();
+                // embedded decision making heuristics
+                if(weights.getWeight(getWeightKey(g)) < successWeight) {
+                    //do nothing to delay the operation
+                    //super.scheduleOperation(op);                     
+                } else {
+                    super.scheduleOperation(op); 
+                    i.remove();
+                    doCount += 1;
+                }
+            }
+        }
+        // If no edges have been added, take the first implication edge (if
+        // any) and perform it.
+        i = siblings.iterator();
+        while(doCount == 0 && i.hasNext()) { // the while is redundant
+            // node operations are processed in the next loop below
+            Operation op = (Operation)i.next();
+            if(op instanceof ImplicationEdge) {
+                super.scheduleOperation(op);
+                i.remove();
+                doCount += 1;
+            }
+        }
+        //if there are no remaining edge operations, then perform the 
+        //remaining node operation (to mark as processed).
+        //check for delayed ops and determine whether it's ok to add node op
+        if(!siblings.isEmpty()) {
+            if(siblings.get(0) instanceof NodeOperation) { 
+                // if all edges are done
+                NodeOperation nodeOp = (NodeOperation)siblings.remove(0);
+                super.scheduleOperation(nodeOp);        
+            }
+        }
+        //put the remaining child edges in the delayed queue
+        Goal g = current.getGoal();
+        if(!siblings.isEmpty()) {
+            delayedOps.put(g, siblings);
+        }
+        //clean up the state variables
+        current = null;
+        isLocal = false;
+    }
+
+    /** criteria for determining when to end this negotiators turn */
+    protected boolean okToEndTurn() {
+        // isDone = 0; // used this to check that delayedOps is really empty
+        // if there are no more delayed op's, then end this negotiator's turn
+        if(delayedOps.isEmpty()) {
+            isDone++;          
+        }
+        //if the negotiation has suceeded or failed, then return true
+        if(getSatisfactionState() != SatisfactionState.UNKNOWN) {
+            isDone++;
+        }
+        //if the threshold for end-turn criteria has been met then return true
+        if(isDone > threshold) {
+            return true;
+        }
+        // the end-turn criteria have not been met
+        return false;
+    }
+
+    /** 
+     * convenience method for determining whether this negotiator has
+     * a deadlock in processing the negotiation. This method can be
+     * overridden is subsequent versions.
+     */
+    protected boolean isStuck() {
+        // if there's no history, we cannot be stuck yet
+        if(super.isStuck()) {
+            if(lastMessage != null) {
+                // if both messages contain no changes, 
+                //then a deadlock has occurred
+                return (lastMessage.getOperationsCount() == 0 );
+            }
+        }
+        return false;
+   }
+
+
+
+}
Index: fedd/abac-src/ttg/process/Strategy.java
===================================================================
--- fedd/abac-src/ttg/process/Strategy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/Strategy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,191 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import java.util.*;
+/**
+ * The strategy handles processing a working list of nodes in the trust target
+ * graph to be processed.
+ */
+public class Strategy extends Observable {
+    /** The context for which this strategy is negotiating */
+    protected NegotiationContext context;
+
+    /** The worklist for nodes to be processed */
+    private LinkedList workList = new LinkedList();
+
+    private SatisfactionState state = 
+	new SatisfactionState(SatisfactionState.UNKNOWN);
+
+    /** The last message sent out */
+    protected Message lastMessage = null;
+
+    /** The current message just received */
+    protected Message currentMessage = null;
+
+    /** creates a new strategy to process a trust negotiation */
+    public Strategy(NegotiationContext context) {
+        this.context = context;
+        //context.setStrategy(this);
+    }
+
+    /** Adds a node to the work list of nodes to be processed */
+    public void addToWorklist(TTGNode node) {
+        if(node != null && workList.add(node)) {
+            debug("worklist", node.getGoal() + " added to worklist");
+            debug("strategy", "worklist = " + workList);
+        }
+    }
+
+    /** Adds a set of node to the work list */
+    public void addToWorklist(TTGNodeSet list) {
+        if(list == null)return;
+        Iterator i = list.values().iterator();
+        while(i.hasNext()) {
+            try {
+                TTGNode node = (TTGNode)i.next();
+                addToWorklist(node);
+            }
+            catch(Exception ex) {
+                ex.printStackTrace(System.err);
+            }
+        }
+    }
+
+    /** determine the current state of negotiation */
+    public int getSatisfactionState() {
+        int state = SatisfactionState.UNKNOWN;
+        try {
+            state = context.getGraph().getRoot().getSatisfactionValue();
+        }
+        catch(Exception ex) {
+            debug("strategy", "graph = " + context.getGraph());
+            debug("strategy", "root = " + context.getGraph().getRoot());
+            ex.printStackTrace(System.err);
+        }
+        if(isStuck() && (state != SatisfactionState.SATISFIED)) {
+            debug("strategy", "Strategy: is stuck!");
+            return SatisfactionState.FAILED;
+        }
+        return state;
+    }
+    /** process nodes on the work list until the list is empty */
+    public SatisfactionState process(Message msg) {
+	TTG graph = context.getGraph();
+	int state = getSatisfactionState();
+
+	addMessage(msg);
+
+	if(state == SatisfactionState.SATISFIED || 
+	   state == SatisfactionState.FAILED) {
+        debug("strategy", "negotiation is complete status: " + state);
+	    return new SatisfactionState(state);
+	}
+	if(isStuck()) {
+        debug("strategy", "negotiation is stuck!");
+	    return new SatisfactionState(SatisfactionState.FAILED);
+	}
+	iterate();
+    addMessage(graph.getChanges());
+	if(isStuck()) {
+        debug("strategy", "negotiation is stuck!");
+	    return new SatisfactionState(SatisfactionState.FAILED);
+	}
+	return new SatisfactionState(state); 
+    }
+
+    /** iterate through the work list until it is empty */
+    public void iterate() {
+        debug("worklist", "worklist = " + workList);
+        setChanged();
+        notifyObservers("location = local");
+        //while worklist is not empty 
+        while(!workList.isEmpty()) {
+            //check for success or failure
+            if(getSatisfactionState() != SatisfactionState.UNKNOWN) {
+                return;
+            }
+            //process node at head of list
+            //add list of nodes returned from process to the worklist
+            TTGNode current = ((TTGNode)workList.removeFirst());
+            setCurrentParent(current);
+            current.process(context);
+            scheduleOperationsForNode(current);
+            debug("strategy", "processing node " + current.getGoal());
+            debug("worklist", "worklist = " + workList);
+        }
+    }
+
+    /** 
+     * Notify the strategy that a new edge needs to be added to the graph.
+     * The strategy is responsible for performing the operation on the graph,
+     * whether the strategy chooses to  defer the operation or not.
+     */
+    public void scheduleOperation(Operation op) {
+        if(op instanceof EdgeOperation) {
+            context.getGraph().performEdge((EdgeOperation)op);
+        } else {
+            context.getGraph().performNode((NodeOperation)op);
+        }
+        
+    }
+
+    /** Place-holder for stingy strategy. */
+    public void addSatisfiedControlChild(TTGNode node) {
+
+    }
+
+
+    /** Place-holder for stingy strategy */
+    public void addNewNode(TTGNode node) {
+        
+    }
+
+    /** 
+     * convenience method for determining whether this negotiator has
+     * a deadlock in processing the negotiation. This method can be
+     * overridden is subsequent versions.
+     */
+    protected boolean isStuck() {
+        // if there's no history, we cannot be stuck yet
+        if(currentMessage == null)
+            return false;
+        // if both messages contain no changes, then a deadlock has occurred
+        return (currentMessage.getOperationsCount() == 0 );
+   }
+
+    /** 
+     * add the current message to the queue. Note: the initial message will 
+     * also be null.
+     */
+    protected void addMessage(Message msg) {
+        lastMessage = currentMessage;
+        currentMessage = msg;
+    }
+
+
+    /** Note the beginning of a new parent node being processed */
+    protected void setCurrentParent(TTGNode parent) {
+        
+    }
+
+    /** Note the conclusion of a new parent node being processed */
+    protected void scheduleOperationsForNode(TTGNode parent) {
+
+    }
+
+    /** */
+    protected void debug(String key, String message) {
+	StringBuffer buff = new StringBuffer("Strategy[");
+	buff.append(context.getSelf()).append("]: ").append(message);
+	Debug.debug(key, buff.toString());
+    }
+
+    /** */
+    public void addObserver(Observer o) {
+        super.addObserver(o);
+        setChanged();
+        notifyObservers("location = init");
+    }
+
+}
Index: fedd/abac-src/ttg/process/StrategyFactory.java
===================================================================
--- fedd/abac-src/ttg/process/StrategyFactory.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/StrategyFactory.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,32 @@
+package com.nailabs.abac.process;
+
+import java.util.*;
+
+/**
+ * Factory for creating a specific strategy.
+ */
+public class StrategyFactory {
+
+    public static Strategy getStrategy(HashMap config) {
+        Strategy strat = null;
+        System.out.println("config = " + config);
+        Properties props = (Properties)config.get("Strategy");
+        String type = props.getProperty("type");
+        NegotiationContext context = (NegotiationContext)config.get("context");
+        if(type == null) {                 // if no config then use default 
+            strat = new Strategy(context);
+            System.out.print("Creating default strategy for ");
+        } else if(type.equalsIgnoreCase("Stingy")) { 
+            // stingy strategy construction
+            StingyStrategy stingy = new StingyStrategy(context, props);
+            System.out.print("Creating stingy strategy for ");
+            strat = stingy;
+        } else {                           // default strategy construction
+            strat = new Strategy(context);
+            System.out.print("Creating default strategy for ");
+        }
+        System.out.println(context.getSelf());
+        return strat;
+    }
+
+}
Index: fedd/abac-src/ttg/process/TTG.java
===================================================================
--- fedd/abac-src/ttg/process/TTG.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/TTG.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,421 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.test.*;
+import com.nailabs.abac.credential.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.engine.*;
+
+import edu.stanford.rt.credential.CredentialDomain;
+import edu.stanford.rt.credential.CredentialStore;
+import edu.stanford.rt.credential.RTContext;
+import edu.stanford.rt.parser.RTParser;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * A trust target graph (TTG) is used to represent the state of a trust
+ * negotiation in process (one per graph). 
+ * @version	$Id: TTG.java,v 1.50 2003/02/26 00:45:11 jjacobs Exp $	
+
+ */
+public class TTG extends Observable implements Observer { 
+    /** The top-level trust target the system is trying to solve. */
+    protected TargetNode root;
+
+    /** An index of TTGNodes based on their trust targets */
+    protected Hashtable indexByTT = new Hashtable();
+
+    /** The old change list for this graph */
+    protected Message oldDelta =  new Message();
+
+    /** The current change list for this graph */
+    protected Message newDelta = new Message();
+
+    /** A set of all previoussent credentials */
+    protected HashSet outCache = new HashSet();
+
+    /** A graph engine for storing remotely held credential */
+    protected GraphEngine oppoCreds = null;
+
+    /** An RTML parser for de-serializing RTML evidence */
+    protected RTParser parser = null;
+    
+    /** An RTML context for incoming opponent's credentials */
+    protected RTContext rtc = null;
+
+    /** A context for a single trust negotiation */
+    protected NegotiationContext context;
+
+    /** Create a trust target graph for a specific negotiation */
+    public TTG(NegotiationContext context){
+	this.context = context;
+	if(context.getFrontier() instanceof RtmlFrontier) {
+	    try {
+		parser = new RTParser();
+		rtc = new RTContext(parser);
+		oppoCreds = new RtmlEngine(new CredentialStore(parser));
+	    }
+	    catch(Exception ex) {
+		debug("rtml", ex.getMessage());
+	    }
+	} else {
+	    oppoCreds = new GraphEngine();
+	}
+    }
+
+    /** Propagates node state change information to a graph observer */
+    public void update(Observable o, Object arg) {
+	//if(o instanceof TTGNode) {
+	setChanged();
+	notifyObservers(arg);
+	//}
+	//else {
+	//debug("update", "received unexpected observation from " + arg);
+	//}
+    }
+
+    /**
+     * This returns an internal list of all node in the trust target graph.
+     * WARNING: this should be a privileged function for production use. Also,
+     * any changes to the TTG will invalidate this iterator!
+     */
+    public Iterator getNodes() {
+        return indexByTT.values().iterator();
+    }
+
+    public TTGNode getNode(Goal key) {
+	TTGNode node = getNodeByHash(key);
+	if(node == null) {
+	    node = TTGNode.createNode(key);
+	    putNodeByHash(node);
+	    debug("node", "initialized node for " + key);
+	}
+	else {
+	    debug("node", "found node for " + key);
+
+	}
+	return node;
+    }
+
+    /** Access a trust target node by the goal it represents */
+    public TTGNode getNodeByHash(Goal key) {
+	return (TTGNode)indexByTT.get(key.toString());
+    }
+
+    /** Entry point for global or local changes. */
+    public void putNodeByHash(TTGNode node) {
+	indexByTT.put(node.getGoal().toString(), node);
+	debug("node", "putting " + node.getGoal());
+	node.init(context);
+	context.getStrategy().addToWorklist(node);
+	context.getStrategy().addNewNode(node);
+	setChanged();
+	notifyObservers((Object)node);
+    
+    }
+
+    public void putRoot(TargetNode node) {
+	debug("root", "putting root" + node);
+	root = node;
+	setChanged();
+	notifyObservers((Object)node);
+    }
+
+    /** A method to reset the change list at the end of a processing cycle */
+    public void reset() { 
+        //consolidate credentials 
+        Iterator i = newDelta.getEvidence();
+        while(i.hasNext()) {
+            Object potential = i.next();
+            if(outCache.contains(potential)) {
+                i.remove();
+            } else {
+                outCache.add(potential);
+            }
+        }
+        oldDelta = newDelta;    // swap out the deltas 
+        newDelta = new Message();     
+        setChanged();           // notify observers of the changed message
+        notifyObservers((Object)oldDelta);
+    }
+
+    /** Accessor method for the change list on the graph and resets the list */
+    public Message getChanges() {
+	return newDelta;
+    }
+    
+    public boolean verifyEvidence(Operation op) {
+        Entity self = context.getSelf();
+        if(op instanceof LinkingImplicationEdge) {
+            return false;
+        }
+        if((op instanceof ImplicationEdge)) { 
+            Goal g = ((EdgeOperation)op).getParent();
+            debug("message", "verifying operation " + op);
+            return(self.equals(g.getVerifier()));
+        }
+        debug("message", "not verifying operation " + op);
+        return false;
+    }
+
+    /** boolean query to determine whether the sepcified goal needs evidence */
+    public boolean provideEvidence(Operation edge) {
+        Goal g = ((EdgeOperation)edge).getParent();
+        Entity self = context.getSelf();
+        return (!self.equals(g.getVerifier()));
+    }
+
+    /** Update this graph with changes contained in the specified message */
+    public void update(Message msg) throws Exception {
+	setChanged();
+	//notifyObservers("<Update location=\"remote\">\n");
+	notifyObservers("location = remote");
+	Iterator ev = msg.getEvidence();
+	while(ev.hasNext()) {
+	    Object eObj = ev.next();
+	    if(eObj instanceof String) {
+		String xml = (String) eObj;
+		InputStream in = new ByteArrayInputStream(xml.getBytes());
+		CredentialDomain domain = 
+		    parser.parseCredentialDomain(in, rtc);
+		((RtmlEngine)oppoCreds).addDomain(domain);
+		debug("message", "received evidence = " + domain);
+	    }
+	    else {
+		StaticCredential credential = (StaticCredential)eObj;
+		Debug.rbtmStart();
+		oppoCreds.addCredential(credential);        
+		Debug.rbtmStop();
+		debug("message", "received evidence = " + credential);
+	    }
+	}
+	Iterator operations = msg.getOperations();
+	while(operations.hasNext()) {
+	    Operation op = (Operation)operations.next();
+	    debug("message", "performing op " + op);
+	    if(verifyEvidence(op)) {
+		EdgeOperation edgeOp = (EdgeOperation)op;
+		TrustTarget parent = (TrustTarget)edgeOp.getParent();
+		TrustTarget child = (TrustTarget)edgeOp.getChild();
+		HashSet evidence = null;
+		
+		//try {
+                EntityExpression parentRole = parent.getTargetRole();
+                EntityExpression childRole = child.getTargetRole();
+                debug("message", "chain search from " + 
+                      parentRole + " to " + childRole);
+                Debug.rbtmStart();                
+                oppoCreds.backwardSearch(parentRole);
+                if(parentRole.equals(childRole)) {
+                    debug("message", "roles are equal bailing out now!");
+                } else {
+                    evidence = oppoCreds.getChain(parentRole, childRole);
+                    // }
+		    Debug.rbtmStop();
+		    //} catch(Exception ex) {
+		    //ex.printStackTrace();
+		    //throw(new java.rmi.RemoteException("Unjustified implication!!"));
+		}
+		edgeOp.setEvidence(evidence);
+		debug("message", "evidence = " + evidence);
+	    }
+	    setChanged();
+	    notifyObservers((Object)op);
+	    op.perform(this);
+	} 
+	setChanged();
+	//notifyObservers("</Update>\n");
+    }
+
+
+    /** 
+     * Accessor method for of root of graph. This is necessary to traverse
+     * the graph. 
+     * @returns the root node which may be any TTGNode descendent.
+     */
+    public TargetNode getRoot() {
+	return root;
+    }
+
+
+    // Methods in this section are recorded in the delta list
+
+    /** 
+     * Insert a new root node for this graph. 
+     * <I>This is a global operation</I>
+     */
+    public void setRoot(TrustTarget target) {
+	debug("root", "setting root = " + target);
+	NodeOperation op = new NodeOperation
+	    (target, target.getInitialProcessingState(context), true);
+	setChanged();
+	notifyObservers(op);
+	op.perform(this);
+	newDelta.addOperation(op);
+    }
+    
+    /**
+     * Mark a node in the graph as opponent processed.
+     */
+    public void setOpponentProcessed(Goal id) {
+	//TTGNode node = getNode(id);
+	//ProcessingState state = node.getProcessingState();
+	//state.opponentProcess(state);
+	setNode(id, new ProcessingState(false, true));
+    }
+
+    /**
+     * Mark a node in the graph as verifier processed.
+     */
+    public void setVerifierProcessed(Goal id) {
+	//TTGNode node = getNode(id);
+	//ProcessingState state = node.getProcessingState();
+	//state.verifierProcess();
+	setNode(id, new ProcessingState(true, false));
+    }
+
+
+    /**
+     * Add a root or modify a node to this TTG and replicate the changes on 
+     * the opponent's TTG.
+     * <I>This is a global operation</I>
+     */
+    public void setNode(Goal id, ProcessingState state)
+    {
+        ProcessingState copy = new ProcessingState();
+        copy.update(state);
+        NodeOperation nodeOp = new NodeOperation(id, copy); 
+        context.getStrategy().scheduleOperation(nodeOp);
+    }
+
+    /** actually performs the node operation on this graph */
+    public void performNode(NodeOperation nodeOp) {
+        // This is slightly different than perform edge although they
+        // could possibly be merged into a single performOperation method
+        nodeOp.perform(this);
+        newDelta.addOperation((Operation)nodeOp);
+        setChanged();
+        notifyObservers((Object)nodeOp);
+    }
+
+    /** actually performs a previously scheduled edge operation */
+    public void performEdge(EdgeOperation edgeOp) 
+    {
+        if(edgeOp instanceof LinkingImplicationEdge) {
+            setChanged();
+            notifyObservers("location = async");
+        }
+        setChanged();
+        notifyObservers((Object)edgeOp);
+        edgeOp.perform(this);
+        if(edgeOp instanceof ImplicationEdge && provideEvidence(edgeOp)) {
+            debug("message", " %%%% adding evidence for " + edgeOp.toString());
+            newDelta.addOperation((Operation)edgeOp);
+        } else {
+            debug("message", " %%%% not adding evidence for" + 
+                  edgeOp.toString());
+            newDelta.addOperationWithoutEvidence((Operation)edgeOp);
+        }
+        if(edgeOp instanceof LinkingImplicationEdge) {
+            setChanged();
+            notifyObservers("location = sync");
+        }
+    }
+
+    /**
+     * Add a new control edge to this TTG and replicate the changes on the 
+     * opponent's TTG.
+     * <I>This is a global operation</I>
+     */
+    public void addControlEdge(Goal parent, Goal child)
+    {
+        TTGNode cnode = getNodeByHash(child);
+        ProcessingState state =  (cnode == null)? 
+            child.getInitialProcessingState(context): null;
+        EdgeOperation edgeOp = new ControlEdge(parent, child, state);
+        context.getStrategy().scheduleOperation(edgeOp);
+    }
+
+    /**
+     * Add a new implication edge to this TTG and replicate the changes on the 
+     * opponent's TTG.
+     * <I>This is a global operation</I>
+     */
+    public void addImplicationEdge(Goal parent, Goal child, HashSet creds) {
+        TTGNode cnode = getNodeByHash(child);
+        //debug("node", "implication cnode = " + cnode); 
+        ProcessingState state = (cnode == null)? 
+            child.getInitialProcessingState(context): null;
+        ImplicationEdge edgeOp = 
+            new ImplicationEdge(parent, child,  state, creds);
+        context.getStrategy().scheduleOperation(edgeOp);
+    }
+
+    /**
+     * Add a new intersection edge to this TTG and replicate the edge on the
+     * opponent's TTG. <i>This is a global operation</i>
+     */
+    public void addIntersectionEdge(TrustTarget parent, TrustTarget child) {
+        TargetNode cnode = (TargetNode)getNodeByHash(child);
+        debug("node", "implication cnode = " + cnode); 
+        ProcessingState state = (cnode == null)? 
+            child.getInitialProcessingState(context): null;
+        IntersectionEdge edgeOp = new IntersectionEdge(parent, child,  state);
+        context.getStrategy().scheduleOperation(edgeOp);        
+    }
+
+    public void addLinkingMonitorEdge(TrustTarget parent, LinkingGoal child) {
+        TTGNode cnode = getNodeByHash(child);
+        ProcessingState state =  (cnode == null)? 
+            child.getInitialProcessingState(context): null;
+        EdgeOperation edgeOp = new LinkingMonitorEdge(parent, child, state);
+        context.getStrategy().scheduleOperation(edgeOp);
+    }
+
+    public void addLinkingSolutionEdge(LinkingGoal monitor, TrustTarget soln) {
+        TTGNode cnode = getNodeByHash(soln);
+        ProcessingState state =  (cnode == null)? 
+            soln.getInitialProcessingState(context): null;
+        EdgeOperation edgeOp = new LinkingSolutionEdge(monitor, soln, state);
+        context.getStrategy().scheduleOperation(edgeOp);
+    }
+
+    public void addLinkingImplicationEdge(TrustTarget parent, TrustTarget child)
+    {
+        TTGNode cnode = getNodeByHash(child);
+        ProcessingState state =  (cnode == null)? 
+            child.getInitialProcessingState(context): null;
+        EdgeOperation edgeOp = 
+            new LinkingImplicationEdge(parent, child, state);
+        context.getStrategy().scheduleOperation(edgeOp);
+    }
+
+    /** Friendly debugging convenience method */
+    protected void debug(String level, String message) {
+	StringBuffer buff = new StringBuffer("TTG[");
+	buff.append(context.getSelf()).append("]: ").append(message);
+	Debug.debug(level, buff.toString());
+    }
+
+
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[TTG EntityID=");
+	buff.append(context.getSelf().toString()).append("\n");
+	Iterator i = indexByTT.keySet().iterator();
+	while(i.hasNext()) {
+	    buff.append("\t").append(i.next()).append("\n");
+	}
+	buff.append("]");
+	return buff.toString();
+    }
+
+}
+
+
+
+
+
+
+
Index: fedd/abac-src/ttg/process/WeightTable.java
===================================================================
--- fedd/abac-src/ttg/process/WeightTable.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/WeightTable.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,92 @@
+package com.nailabs.abac.process;
+
+import edu.stanford.peer.rbtm.credential.*;
+import java.util.*;
+import java.io.*;
+
+public class WeightTable {
+
+    private int serialNo = 0;
+
+    protected Hashtable table = new Hashtable(20);
+
+    protected float p = 0.50f;
+
+    protected final float SAT = 1.0f;
+
+    protected final float FAIL = 0.0f;
+
+    public float DEFAULT = 1.0f;
+
+    public WeightTable(String file, float p) {
+        this(file);
+        this.p  = p;
+    }
+
+    public WeightTable(String file) { load(file);  }
+
+    public void load(String filename) {
+        try {
+            BufferedReader in = new BufferedReader(new FileReader(filename));
+            while(true) {
+                String line = in.readLine();
+                StringTokenizer st = new StringTokenizer(line, "=");
+                EntityExpression expr = 
+                    StaticCredential.getEntityExpression(st.nextToken());
+                Float weight = new Float(st.nextToken());
+                table.put(expr, weight);
+            }
+        } catch(Exception ex) {
+            //ex.printStackTrace();
+        }
+    }
+  
+    public void save(String filename) {
+        try {
+            PrintStream out = new PrintStream(new FileOutputStream(filename));
+            Iterator i = table.keySet().iterator();
+            while(i.hasNext()) {
+                EntityExpression key = (EntityExpression)i.next();
+                Float entry = (Float)table.get(key);
+                out.println(key + "=" + getWeight(key));
+            }
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    public float getWeight(EntityExpression r) {
+        Float val = (Float)table.get(r);
+        if(val == null) {
+            val = new Float(DEFAULT); 
+            table.put(r, val);
+        }
+        return val.floatValue();
+    }
+
+    public void addSatisfied(EntityExpression r) { 
+        Float val =  (Float)table.get(r);
+        if(val == null) {
+            val = new Float(DEFAULT);
+        }
+        val = new Float(update(val.floatValue(), SAT));
+        table.put(r, val);
+    }
+
+    public void addFailed(EntityExpression r) {
+        Float val =  (Float)table.get(r);
+        if(val == null) {
+            val = new Float(DEFAULT);
+        }
+        val = new Float(update(val.floatValue(), FAIL));
+        table.put(r, val);
+    }
+
+    protected float update(float val, float u) {
+        if(u == 1.0f) 
+            return 1.0f;
+        else 
+            return (val * (1.0f - p) + u * p);
+    }
+
+}
Index: fedd/abac-src/ttg/process/package.html
===================================================================
--- fedd/abac-src/ttg/process/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,4 @@
+<body>
+<p> This package includes all the classes required for processing a trust 
+    negotiation, including the communication and processing algorithms. </p>
+</body>
