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");
+    }
+
+}
