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
+
Index: fedd/abac-src/rbtm/engine/old/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/engine/old/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,7 @@
+/AbstractProofNode1.java1/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/IntersectionProofNode.java1/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/OldProofNode.java1/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/PartialSolution.java1/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/ProofNode.java1/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/ProofNode1.java1/1.1.1.1/Tue Nov 13 17:28:45 2001//
+D
Index: fedd/abac-src/rbtm/engine/old/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/engine/old/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/engine/old
Index: fedd/abac-src/rbtm/engine/old/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/engine/old/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/engine/old/IntersectionProofNode.java1
===================================================================
--- fedd/abac-src/rbtm/engine/old/IntersectionProofNode.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/IntersectionProofNode.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,47 @@
+class IntersectionProofNode extends ProofNode
+{
+    private SolutionListener watcher = new IntersectionMonitor();
+    private int numOfParts;
+
+    IntersectionProofNode(Intersection re) { 
+        super(re); 
+        numOfParts = re.numOfParts();
+    }
+
+    void backwardProcess() {
+        super.backwardProcess();
+        Iterator it = (Intersection)roleExp.getParts();
+        while (it.hasNext()) {
+            EntityExpression re = (EntityExpression)it.next();
+            ProofNode node = addBackwardNode(firstRole);
+            node.backwardMgr.addListener(watcher);
+        }
+    }
+
+    class IntersectionMonitor implements SolutionListener 
+    {
+        // Maps a solution to a counter, no source is needed
+        private HashMap  solutions;
+
+        public void solutionAdded(ProofNode s, ProofSolution r) {
+            debugInfo("Solution added: "+roleExp+"; "+s.roleExp+"; "+r);
+            if (! solutions.containsKey(r)) {   // first piece
+                solutions.put(r, new Integer(1));  
+            } else { 
+                int n = ((Integer)solutions.get(r)).intValue();
+                n ++;
+                solutions.put(r, new Integer(n));
+                if (n == numOfParts) {  // all pieces are found
+                    backwardMgr.solutionAdded(IntersectionProofNode.this, r);
+                }
+            }
+        }
+    }
+
+    /* forwardProcess has nothing special
+    void forwardProcess() {
+        super.forwardProcess();
+        
+    } */
+} // End of class IntersectionProofNode
+
Index: fedd/abac-src/rbtm/engine/old/OldProofNode.java1
===================================================================
--- fedd/abac-src/rbtm/engine/old/OldProofNode.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/OldProofNode.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,61 @@
+    public class ProofNode
+    {
+        EntityExpression  roleExp;    // What EntityExpression this node is about
+        SolutionManager forwardMgr = new SolutionManager(); 
+        SolutionManager backwardMgr = new SolutionManager();
+
+        ProofNode (EntityExpression re) {
+            debugInfo("A new node is created for " + re);
+            roleExp = re;
+            forwardMgr.solutionAdded(this, roleExp);
+            backwardMgr.solutionAdded(this, roleExp);
+        }
+
+        // The method that does the work when we visit a node
+        void forwardProcess() {
+            // first go over all credentials that have this as subject
+            Iterator  credIt = findCredentialsBySubject(roleExp);
+            while (credIt.hasNext()) { 
+                StaticCredential credential = (StaticCredential) credIt.next();
+                ProofNode node = addForwardNode(credential.getDefinedRole());
+                addProofEdge(this, node, credential);
+            }
+        }
+
+        void backwardProcess() {
+        }
+
+        /**
+         * Class SolutionManager implements listener management and solution 
+         * management.
+         */
+       class SolutionManager implements SolutionListener
+       {
+            private HashMap    solutions = new HashMap();
+            private LinkedList listeners = new LinkedList();
+
+            public void solutionAdded(ProofNode s, ProofSolution r) {
+                debugInfo("Solution added: " + roleExp + "; " + s.roleExp + "; " + r);
+                if (! solutions.containsKey(r)) {   // when solution r is new
+                    solutions.put(r, new SmallSet(s));  // add solution together with source
+                    Object[] lisArray = listeners.toArray();    // inform all listeners
+                    for (int i=0; i<lisArray.length; i++) {
+                        ((SolutionListener)lisArray[i]).solutionAdded(ProofNode.this, r);
+                    }
+                } else if (trackAll) {
+                    ((SmallSet)solutions.get(r)).add(s);
+                }
+            }
+
+            void addListener(SolutionListener sl) {
+                listeners.add(sl);
+                // inform the listener of existing solutions
+                Object[] sols = solutions.keySet().toArray();  
+                for (int i=0; i<sols.length; i++) {
+                     sl.solutionAdded(ProofNode.this, (EntityExpression)(sols[i]));
+                }
+            }
+
+            Set getSolutions()     {  return solutions.keySet();     }
+        } // End of class SolutionManager
+    } // End of class ProofNode
Index: fedd/abac-src/rbtm/engine/old/PartialSolution.java1
===================================================================
--- fedd/abac-src/rbtm/engine/old/PartialSolution.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/PartialSolution.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,16 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+
+public class PartialSolution implements ProofSolution
+{
+    private Intersection re;
+    private Integer index;
+    PartialSolution(Intersection r, int i) {
+        re = r;
+        index = new Integer(i);
+    }
+    
+    public Intersection getIntersection() { return re; }
+    public Integer getNumber() { return index; }
+}
Index: fedd/abac-src/rbtm/engine/old/ProofNode.java1
===================================================================
--- fedd/abac-src/rbtm/engine/old/ProofNode.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/ProofNode.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,64 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/*
+ */
+public interface ProofNode extends BackwardSolutionListener, ForwardSolutionListener
+{
+	EntityExpression getRoleExp();
+
+	void addBackwardListener(BackwardSolutionListener sl);
+
+	/**
+	 * Process this node for search in the backward direction.  The 
+	 * implementation of this method should find all nodes that can reach
+	 * this node directly and do appropriate things.
+	 */
+	void backwardProcess();
+
+	void invalidateBackward();
+
+	void addForwardListener(ForwardSolutionListener sl);
+
+	void forwardProcess();
+
+	void invalidateForward();
+
+	/**
+	 * add a node as a parent to this node
+	 * @param  node: the parent node
+	 */
+	void addParent(ProofNode node, Object evidence);
+
+	void addChild(ProofNode node, Object evidence);
+
+	ResultEvidenceMap getForwardSolutions();
+
+	ResultEvidenceMap getBackwardSolutions();
+
+	/**
+	 * Enable this node for backward searching, it then should store all 
+	 * backward solutions (entities that are member of this node).
+	 */
+	// void enableAllBackwardGoals();
+
+	/**
+     * If one only wants to know whether this node has some particular 
+	 * backward solutions, and doesn't care about others, then one can use 
+	 * this call to tell this proof node.  It might improve efficiency in 
+	 * bi-direction search.
+	 */
+    // void enableBackwardGoal(EntityExpression g);
+
+    // void enableAllForwardGoals();
+    // void enableForwardGoal(EntityExpression g);	
+
+    // boolean hasParent(ProofNode node);
+    // boolean hasChild(ProofNode node);
+
+} // End of class ProofNode
+
Index: fedd/abac-src/rbtm/engine/old/ProofNode1.java1
===================================================================
--- fedd/abac-src/rbtm/engine/old/ProofNode1.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/old/ProofNode1.java1	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,60 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/*
+ */
+public interface ProofNode extends BackwardSolutionListener, ForwardSolutionListener
+{
+	EntityExpression getRoleExp();
+
+	void addBackwardListener(BackwardSolutionListener sl);
+
+	/**
+	 * Process this node for search in the backward direction.  The 
+	 * implementation of this method should find all nodes that can reach
+	 * this node directly and do appropriate things.
+	 */
+	void backwardProcess();
+
+	void addForwardListener(ForwardSolutionListener sl);
+
+	void forwardProcess();
+
+	/**
+	 * add a node as a parent to this node
+	 * @param  node: the parent node
+	 */
+	void addParent(ProofNode node, Object evidence);
+
+	void addChild(ProofNode node, Object evidence);
+
+	Set getForwardSolutions();
+
+	Set getBackwardSolutions();
+
+	/**
+	 * Enable this node for backward searching, it then should store all 
+	 * backward solutions (entities that are member of this node).
+	 */
+	// void enableAllBackwardGoals();
+
+	/**
+     * If one only wants to know whether this node has some particular 
+	 * backward solutions, and doesn't care about others, then one can use 
+	 * this call to tell this proof node.  It might improve efficiency in 
+	 * bi-direction search.
+	 */
+    // void enableBackwardGoal(EntityExpression g);
+
+    // void enableAllForwardGoals();
+    // void enableForwardGoal(EntityExpression g);	
+
+    // boolean hasParent(ProofNode node);
+    // boolean hasChild(ProofNode node);
+
+} // End of class ProofNode
+
