Index: fedd/abac-src/ttg/trust/TargetNode.java
===================================================================
--- fedd/abac-src/ttg/trust/TargetNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/trust/TargetNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,200 @@
+package com.nailabs.abac.trust;
+
+import com.nailabs.abac.process.*;
+import edu.stanford.peer.rbtm.credential.*;
+import java.util.*;
+
+/**
+ * A target node is the parent class for the <CODE>*TTNode</CODE> classes, 
+ * which have the following common elements: satisfaction state, implication
+ * parents, and control parents.
+ */
+public abstract class TargetNode extends TTGNode 
+    implements SatisfactionListener {
+
+    /** The satisfaction state of this node */
+    protected SatisfactionState satisfier;
+    
+    /**
+     * A set of implication parent nodes. Each parent represents a separate
+     * edge in the trust target graph. 
+     * @see com.nailabs.abac.process.ImplicationEdge
+     */
+    protected TTGNodeSet implicationParents = new TTGNodeSet();
+
+    
+    /**
+     * A set of control parent nodes. Each parent represents a separate edge
+     * in the trust target graph.
+     * @see com.nailabs.abac.process.ControlEdge
+     */
+    protected TTGNodeSet controlParents = new TTGNodeSet();
+    
+    /** Default constructor for a TargetNode */
+    public TargetNode(TrustTarget target) {
+	super(target);
+	subName = "TargetNode";
+	processor = new ProcessingState();
+	satisfier = new SatisfactionState(SatisfactionState.UNKNOWN);
+	satisfier.addObserver(this);
+    }
+    
+    /** Constructor which also creates a trust target implicitly */
+    public TargetNode(Entity verifier, EntityExpression target, Entity subject)
+	throws CredentialParsingException, TrustTargetParsingException 
+    {
+	this(new TrustTarget(verifier, target, subject));
+    }
+
+   /** 
+     * This method should be polymorphic since children will have customized
+     * fields.
+     */
+    public void update(Observable obs, Object obj) {
+	if(obs == satisfier) {
+	    setChanged();
+	    notifyObservers(satisfier);
+	} else {
+	    super.update(obs, obj);
+	}
+    }
+
+
+    /** Read-only accessor method for the satisfaction state. */
+    public int getSatisfactionValue() { 
+	if(satisfier == null) return -1;
+	return satisfier.getState(); 
+    }
+
+    /**
+     * Accessor method for setting the satisfaction state field.
+     * @param state The new satisfaction state.
+     * @return The old satisfaction state.
+     */
+    protected SatisfactionState setState(SatisfactionState state) {
+	SatisfactionState old = satisfier;
+	satisfier = state;
+	debug("satisfaction",
+	      "satisfaction state for " + getGoal() + " = " + state);
+	//if(!satisfier.equals(old)) {
+    setChanged();
+    notifyObservers(state);
+	//}
+	return old;
+    }
+
+    /** 
+     * Process a node whose trust target verifier entity is not self 
+     * @see RMINegotiator
+     */
+    public abstract void opponentProcess(NegotiationContext context);
+
+    /** 
+     * Process a node whose trust target verifier entity is self 
+     * @see RMINegotiator
+     */
+    public abstract void verifierProcess(NegotiationContext context);
+
+    /**
+     * Records the new state and then propagates it to the parent listeners.
+     * @param state The new satisfaction state to be propagated. 
+     */
+    public  TTGNodeSet receive(TrustTarget source, SatisfactionState state) {
+	TTGNodeSet results = new TTGNodeSet();
+	debug("satisfaction", getGoal() + " received " + state + " from " +
+	      source);
+	// if the state has not changed stop propagating it
+	if(!(this instanceof TrivialTTNode)) {
+	    if(satisfier.getState() == state.getState() ||
+	       getGoal().equals(source)) {
+		debug("satisfaction",
+		      "not trivial and received same state bailing out now!");
+		return results;
+	    }
+	}
+	setState(state);
+	//}
+	Iterator i = implicationParents.values().iterator();
+	while(i.hasNext()) {
+	    try { // this will fail if the parent is a linking goal
+		SatisfactionListener listener = (SatisfactionListener)i.next();
+		TTGNodeSet branchResult = listener.receive((TrustTarget)getGoal(), state);
+		if(branchResult == null && branchResult.size() > 0) {
+		    results.addAll(branchResult);
+		}
+	    }
+	    catch(Exception ex) { // to print out exception uncomment
+		ex.printStackTrace();
+	    }
+	}
+ 	//if(state.getState() == SatisfactionState.FAILED) {
+    //bail out for now...
+    //return results;
+    //}
+    // Work with the control parents
+	i = controlParents.values().iterator();
+	Strategy strategy = context.getStrategy();
+    //if satisfied and there exist control parent(s), then notify strategy
+    if(state.getState() == SatisfactionState.SATISFIED) {
+        if(i.hasNext()) {
+            //notify strategy that a control child has been satisfied
+            strategy.addSatisfiedControlChild(this); 
+        }
+        while(i.hasNext()) { //place each control parent on the worklist
+            TTGNode controlParent = (TTGNode)i.next();
+            strategy.addToWorklist(controlParent);
+        }
+	}
+	System.out.println("TargetNode: " + getGoal() + "exiting receive method");
+	return results;
+    }
+
+    /** Add a goal as an implication parent of this node. */
+    public void addImplicationParent(TargetNode parent) {
+        if(parent != null){ 
+            debug("node", "adding implication parent");
+            implicationParents.add(parent);
+            parent.receive((TrustTarget)getGoal(), satisfier);
+        }
+    }
+
+    /** Add a goal as a control parent of this node. */ 
+    public void addControlParent(TargetNode parent) {
+	if(parent != null) { 
+	    controlParents.add(parent);
+	    if(getSatisfactionValue() == SatisfactionState.SATISFIED) {
+		context.getStrategy().addToWorklist(parent);
+	    }
+	    //setChanged();
+	    //notifyObservers();
+	}
+	//receive((TrustTarget)getGoal(), satisfier);
+    }
+
+    /** Convenience accessor method for the target role expression */
+    public EntityExpression getTargetExpression() { 
+	return ((TrustTarget)getGoal()).getTargetRole(); 
+    }
+
+    public String toXML() {
+	return toXML(new String(""));
+    }
+
+    public String toXML(String options) {
+	return toXML(options, satisfier.toXML());
+    }
+
+    /** Print out a node in human readable format */
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[");
+	buff.append(getClass().getName()).append(", ");
+	buff.append(processor).append(", ");
+	buff.append(satisfier).append(", ");
+	buff.append(getGoal().toString()).append("]");
+	return buff.toString();
+    }
+
+}
+
+
+ 
