Index: fedd/abac-src/rbtm/engine/old/AbstractProofNode1.java1
===================================================================
--- fedd/abac-src/rbtm/engine/old/AbstractProofNode1.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/AbstractProofNode1.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,256 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/*
+ */
+public abstract class AbstractProofNode implements ProofNode
+{
+	/** The EntityExpression this node is about. */
+    EntityExpression   _roleExp;
+
+	/** The proof _graph this node is in, this reference is used while processing 
+	    this node */
+    ProofGraph         _graph;
+
+    /** Nodes that can reach this node directly, evidences are credentials. */
+    protected HashSet  parents;  
+
+    /** Nodes that this node can reach directly, evidecens are credentials. */
+    protected HashSet  children; 
+
+	/** Backward solutions on this node  */
+    protected HashSet  backwardSolutions;
+
+	/** Forward solutions on this node */
+    protected HashSet  forwardSolutions;
+
+    protected ArrayList  backwardListeners;
+    protected ArrayList  forwardListeners;
+
+    AbstractProofNode (ProofGraph graph, EntityExpression re, boolean trackAll)
+    {
+		_graph = graph;
+        _roleExp = re;
+        Debug.debugInfo("A new node is created for " + re);
+
+        parents = new ResultEvidenceMap(trackAll);  
+        children = new ResultEvidenceMap(trackAll); 
+        backwardSolutions = new ResultEvidenceMap(trackAll);
+		forwardSolutions = new ResultEvidenceMap(trackAll);
+    
+		backwardListeners = new HashSet();
+		forwardListeners = new HashSet();
+
+		// Call this in constructor instead of process methods, because
+		// we want to record the fact that this node has been reached even 
+		// without further processing
+		finishInit();
+    }
+
+	/** 
+	 * This method adds the node itself as both a forward solution and a backward
+	 * aolution to itself.  If this behaviour is not appropriate, this method
+	 * should be overriden.
+	 */
+	protected void finishInit()
+	{
+		ForwardSolution fs = _graph.getForwardSolution(_roleExp);
+		if (fs != null) {
+			forwardSolutionAdded(this, fs);
+		}
+
+		BackwardSolution bs = _graph.getBackwardSolution(_roleExp);
+		if (bs != null) {
+			backwardSolutionAdded(this, bs);
+		}
+	}
+
+	public ProofGraph getGraph() {
+		return _graph;
+	}
+	
+	public EntityExpression getRoleExp() {
+		return _roleExp;
+	}
+
+	public ResultEvidenceMap getForwardSolutions() {
+		return forwardSolutions;
+	}
+
+	public ResultEvidenceMap getBackwardSolutions() {
+		return backwardSolutions;
+	}
+
+    // The method that does the work when we visit a node
+    public void forwardProcess() 
+    {
+        // first step: go over all credentials that have this as subject
+        Iterator  credIt = _graph.findCredentialsBySubject(_roleExp);
+        while (credIt.hasNext()) { 
+            StaticCredential credential = (StaticCredential) credIt.next();
+            ProofNode node = _graph.addForwardNode(credential.getDefinedRole());
+			node.addParent(this, credential);
+            //_graph.addProofEdge(this, node, credential);
+        }
+
+        // second step: find partial usage of this EntityExpression
+		/*
+        if (_roleExp instanceof Intersection) {
+            return;
+        }
+        credIt = _graph.findCredentialsByPartialSubject(_roleExp);
+        while (credIt.hasNext()) { 
+            StaticCredential credential = (StaticCredential) credIt.next();
+            ProofNode node = _graph.addForwardNode(credential.getDefinedRole());
+            int j = ((Intersection) credential.getSubject()).getIndexOf(_roleExp);
+            forward.solutionAdded(new PartialSolution(_roleExp, j));
+        }
+		*/
+    }
+
+    public void addBackwardListener(BackwardSolutionListener sl) {
+        backwardListeners.add(sl);
+    	propagateBackwardSolutionsTo(sl);
+    }
+
+    public void addForwardListener(ForwardSolutionListener sl) {
+        forwardListeners.add(sl);
+    	propagateForwardSolutionsTo(sl);
+    }
+
+    /**
+     * Add a node as a parent to this node
+     * @param  node: the parent node
+     */
+    public void addParent(ProofNode node, Object evidence) {
+        if (! parents.contains(node.getRoleExp()) {  
+			parents.add(node);
+			addForwardListener(node);
+        }
+    }
+
+    public void addChild(ProofNode node, Object evidence) {
+	    if (children.putResultEvidence(node.getRoleExp(), evidence)) {  
+    		addBackwardListener(node);
+	    }
+    }
+
+    public void backwardSolutionAdded(ProofNode s, BackwardSolution r)
+    {
+        if (backwardSolutions.putResultEvidence(r, s)) {   // when solution r is new
+            Debug.debugInfo("Solution added: " + getRoleExp() + "; " + s.getRoleExp() + "; " + r);
+			propagateBackwardSolution(r);
+        }
+    }
+
+    public void forwardSolutionAdded(ProofNode s, ForwardSolution r) {
+		/*
+       if (r instanceof PartialSolution) {
+            Intersection re = r.getIntersection();
+            Integer index = r.getNumber();
+            HashMap value = (HashMap) partialSols.get(re);
+            if (value == null) {   // first piece
+                value = new HashMap();
+                partialSols.put(re, value);
+            }
+            SmallSet evidences = value.get(index);
+            if (evidences == null) { // A new piece
+                evidences = new SmallSet(s);
+                value.put(index, evidences);
+                if (value.size() == re.getK()) { // have all pieces
+                    // Add an edge from current node to re
+                    // addEdge();
+                }
+            } else if (trackAll) {
+                evidences.add(s);
+            }
+			return;
+        } 
+		*/
+		if (forwardSolutions.putResultEvidence(r, s)) {
+			Debug.debugInfo("Forward solution added to: " + getRoleExp() + "; " + s.getRoleExp() + "; " + r);
+			propagateForwardSolution(r);
+		}
+    }
+
+    protected void propagateBackwardSolutionsTo(BackwardSolutionListener listener)
+    {
+    	Object[] sols = backwardSolutions.resultSet().toArray();
+    	for (int i=0; i<sols.length; i++) {
+        	 listener.backwardSolutionAdded(this, (BackwardSolution)(sols[i]));
+    	}
+    }
+
+    protected void propagateForwardSolutionsTo(ForwardSolutionListener listener)
+    {
+    	Object[] sols = forwardSolutions.resultSet().toArray();
+    	for (int i=0; i<sols.length; i++) {
+        	 listener.forwardSolutionAdded(this, (ForwardSolution)(sols[i]));
+    	}
+    }
+
+    protected void propagateBackwardSolution(BackwardSolution g)
+    {
+    	Object[] listeners = backwardListeners.toArray();
+    	for (int i=0; i<listeners.length; i++) {
+    	    ((BackwardSolutionListener)listeners[i]).backwardSolutionAdded(this, g);
+    	}
+    }
+
+    protected void propagateForwardSolution(ForwardSolution g)
+    {
+    	Object[] listeners = forwardListeners.toArray();
+    	for (int i=0; i<listeners.length; i++) {
+    	    ((ForwardSolutionListener)listeners[i]).forwardSolutionAdded(this, g);
+    	}
+    }
+
+
+    // boolean hasParent(ProofNode node) { return parents.containsResult(node._roleExp); }
+
+
+	//////////// code for SelectiveProofNode
+    /*
+     * The following two fields store desired goals.  Only desired goals are 
+     * passed through edges.  Setting them to null means all goals are 
+     * desired.
+     * In backward search, if child A.r only wants to see one solution, while 
+     * child A.r1.r2 wants to see all solutions.  All goals are desired, so
+     * they are passed to A.r as well.  But A.r should have only one desired
+     * solution, and so A.r will not propagate them further.
+     */
+    // SmallSet  backwardGoals = new SmallSet(); 
+    // SmallSet  forwardGoals = new SmallSet();
+
+    /* 
+    void enableBackwardGoal(EntityExpression g)
+    {
+        if (backwardGoals != null && ! backwardGoals.containsGoal(g)) { 
+    		// has not been enabled before
+            backwardGoals.addGoal(g);
+            if (backwardSoltuions.containsResult(g)) {
+    			propagateBackwardSolution(g);
+            }
+            // Enable this backward goal for all parents
+            Object[] list = parents.toArray();  // inform listeners
+            for (int i=0; i<list.length; i++) {
+                ((ProofNode)list[i]).enableBackwardGoal(g);
+            }
+        }
+    }
+
+    void enableAllBackwardGoals()
+    {
+        if (backwardGoals == null ) {
+            backwardGoals = null;
+            // if have been procesed, loop over all parents, and enable them
+            // if haven't been processed, just enable it
+        }
+    }
+    */
+} // End of class ProofNode
+
