Index: fedd/abac-src/rbtm/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,3 @@
+/Makefile/1.8/Sat Aug  9 00:45:29 2003//
+/RBTMConstants.java/1.3/Mon Dec 17 20:06:14 2001//
+D
Index: fedd/abac-src/rbtm/CVS/Entries.Log
===================================================================
--- fedd/abac-src/rbtm/CVS/Entries.Log	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/CVS/Entries.Log	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,7 @@
+A D/access////
+A D/classes////
+A D/credential////
+A D/doc////
+A D/engine////
+A D/test////
+A D/util////
Index: fedd/abac-src/rbtm/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm
Index: fedd/abac-src/rbtm/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/Makefile
===================================================================
--- fedd/abac-src/rbtm/Makefile	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/Makefile	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,50 @@
+#!/bin/make
+#
+#
+JAVAC=javac
+#JAVAC=jikes 
+CLASSDIR=classes
+CATALINA=/var/tomcat4
+DOCTITLE="Role Based Trust Management"
+WINDOWTITLE="Role Based Trust Management"
+SRCDIR=.
+
+all:		classes jar
+
+doc:		Makefile
+		ln -s . edu; ln -s . stanford;  ln -s . peer; ln -s . rbtm
+		ln -s . com; ln -s . nailabs; ln -s . abac
+		javadoc -package -d doc -sourcepath $(SRCDIR) \
+			-doctitle $(DOCTITLE) \
+			-windowtitle $(WINDOWTITLE) \
+			edu.stanford.peer.rbtm.credential \
+			edu.stanford.peer.rbtm.engine \
+			edu.stanford.peer.rbtm.util \
+			edu.stanford.peer.rbtm.test \
+			edu.stanford.peer.rbtm \
+			com.nailabs.abac.access 
+		rm com; rm nailabs; rm abac
+		rm edu; rm stanford; rm peer; rm rbtm
+
+clean:			
+		@echo Cleaning up class files and javadoc...
+		@rm -rf classes/com classes/edu
+		@touch RBTMConstants.java
+		@rm -rf doc/*
+
+jar:		
+		cd classes; jar cvf rbtm.jar edu
+
+classes:	
+		$(JAVAC) -d $(CLASSDIR) *.java \
+			credential/*.java \
+			engine/*.java \
+			access/*.java \
+			test/*.java \
+			util/*.java 
+
+install: 
+		cp classes/rbtm.jar $(CATALINA)/common/lib/.
+
+
+.PHONY: clean classes jar install doc
Index: fedd/abac-src/rbtm/RBTMConstants.java
===================================================================
--- fedd/abac-src/rbtm/RBTMConstants.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/RBTMConstants.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,14 @@
+package edu.stanford.peer.rbtm;
+
+public interface RBTMConstants
+{
+	static final public int TRACK_NONE = 0;
+	static final public int TRACK_ANY = 1;
+	static final public int TRACK_ALL = 2;
+
+        static final int FACT_MAP_SIZE = 10;
+        static final boolean DEBUG = true;
+
+    
+
+}
Index: fedd/abac-src/rbtm/access/AckFact.java
===================================================================
--- fedd/abac-src/rbtm/access/AckFact.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/access/AckFact.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,82 @@
+package com.nailabs.abac.access;
+
+import edu.stanford.peer.rbtm.credential.*;
+
+public class AckFact {
+
+    /**
+     * This attribute defines the scope of the AckFact instance.
+     */
+    protected RoleName 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(RoleName attribute, EntityExpression req) {
+	this(attribute, DEFAULT, DEFAULT, req);
+    }
+
+    /**
+     * Explicit constructor method. This represents a fully expanded policy
+     * fact.
+     */
+    public AckFact(RoleName 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() { return attribute; }
+
+    /**
+     * 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; }
+}
Index: fedd/abac-src/rbtm/access/AckPolicy.java
===================================================================
--- fedd/abac-src/rbtm/access/AckPolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/access/AckPolicy.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,28 @@
+package com.nailabs.abac.access;
+
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+
+public class AckPolicy implements edu.stanford.peer.rbtm.RBTMConstants {
+
+    public HashMap factMap = new HashMap(FACT_MAP_SIZE);
+    
+    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();
+	}
+    }
+
+    public void addAckFact(Role role, EntityExpression req) {
+	factMap.put(role, req);
+    }
+
+    public EntityExpression requires(Role key) {
+	return (EntityExpression)factMap.get(key);
+    }
+
+}
Index: fedd/abac-src/rbtm/access/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/access/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/access/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,3 @@
+/AckFact.java/1.3/Fri Dec 14 20:17:22 2001//
+/AckPolicy.java/1.1/Fri Dec 14 22:51:32 2001//
+D
Index: fedd/abac-src/rbtm/access/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/access/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/access/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/access
Index: fedd/abac-src/rbtm/access/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/access/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/access/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/classes/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/classes/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/classes/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+D
Index: fedd/abac-src/rbtm/classes/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/classes/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/classes/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/classes
Index: fedd/abac-src/rbtm/classes/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/classes/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/classes/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/credential/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/credential/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,16 @@
+/Credential.java/1.2/Wed May 15 16:46:19 2002//
+/CredentialParsingException.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/Entity.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/EntityExpression.java/1.2/Thu Dec 13 02:11:33 2001//
+/Intersection.java/1.3/Thu Dec  6 01:18:07 2001//
+/LinkedRole.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/PermissionExpression.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/RPermission.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/Role.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/RoleExpression.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/RoleName.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/SimpleEntity.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/SimpleRoleName.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/StaticCredential.java/1.7/Fri May 17 16:17:54 2002//
+/package.html/1.2/Tue Dec 18 01:38:12 2001//
+D
Index: fedd/abac-src/rbtm/credential/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/credential/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/credential
Index: fedd/abac-src/rbtm/credential/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/credential/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/credential/Credential.java
===================================================================
--- fedd/abac-src/rbtm/credential/Credential.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/Credential.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,29 @@
+/*
+ * Credential.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+/**
+ * Credential is the top level class for credentials in RBTM framework.  It is 
+ * an abstract class, and has two direct sub-classes: StaticCredential and 
+ * DynamicCredential.
+ */
+public abstract class Credential implements java.io.Serializable
+                            // extends java.security.cert.Certificate
+{
+    /**
+     * Constructor for Role-Based Trust Management certificates.
+    protected Credential() {
+        super("RBTM");
+    }
+     */
+
+    /**
+     * Get the issuer of this credential.
+     */
+    public abstract Entity getIssuer();
+
+    /** converts the credential into an XML formatted string */
+    public abstract String toXML();
+}
Index: fedd/abac-src/rbtm/credential/CredentialParsingException.java
===================================================================
--- fedd/abac-src/rbtm/credential/CredentialParsingException.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/CredentialParsingException.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,7 @@
+
+package edu.stanford.peer.rbtm.credential;
+
+public class CredentialParsingException extends Exception
+{
+    CredentialParsingException(String info) { super(info); }
+}
Index: fedd/abac-src/rbtm/credential/Entity.java
===================================================================
--- fedd/abac-src/rbtm/credential/Entity.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/Entity.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,13 @@
+/*
+ * Entity.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+/**
+ * An object of the Entity class represents an entity (or a principal) in RBTM.
+ */
+public interface Entity extends EntityExpression, java.io.Serializable, Comparable
+{
+    String getName();
+}
Index: fedd/abac-src/rbtm/credential/EntityExpression.java
===================================================================
--- fedd/abac-src/rbtm/credential/EntityExpression.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/EntityExpression.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,18 @@
+package edu.stanford.peer.rbtm.credential;
+
+import edu.stanford.peer.rbtm.engine.*;
+
+/**
+ * An EntityExpression can be one of the following:
+ * <UL>
+ *   <LI>an Entity
+ *   <LI>a Role
+ *   <LI>a LinkedRole
+ *   <LI>an Intersection.
+ * </UL>
+ *  Currently it is a marker interface
+ */
+public interface EntityExpression 
+		extends ForwardSolution, BackwardSolution, java.io.Serializable
+{
+}
Index: fedd/abac-src/rbtm/credential/Intersection.java
===================================================================
--- fedd/abac-src/rbtm/credential/Intersection.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/Intersection.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,90 @@
+package edu.stanford.peer.rbtm.credential;
+
+import java.util.*;
+
+public class Intersection implements EntityExpression
+{
+    /**
+     * The parts of the intersection
+     */
+    protected LinkedList parts;
+
+    /** 
+     * Default constructor. Expressions to be intersected may be added using
+     * the and() method.
+     */
+    public Intersection() {  parts = new LinkedList(); }
+
+    /**
+     * Default copy constructor. All part references are duplicated, so the
+     * new copy is not relying on the old ones parts list.
+     */
+    public Intersection(Intersection i) {
+	this();
+	Iterator it = i.getParts();
+	while(it.hasNext())
+	    parts.add(it.next());
+    }
+    
+    /**
+     * Adds a new expression to this intersection. And() calls may be 
+     * concatenated similar to appending with a StringBuffer instance.
+     * @param expr An expression to be added (a role or linked role)
+     * @return The updated intersection expression
+     */
+    public Intersection and(EntityExpression expr) {
+	parts.add(expr);
+	return this;
+    }
+
+    /**
+     * Public accessor method for accessing each expression in the 
+     * intersection. 
+     */
+    public Iterator getParts() { return parts.iterator(); }
+
+    /**
+     * Public access method for determining the number of subexpressions
+     * contained in this intersection.
+     */
+    public int getPartsCount() { return parts.size(); }
+
+    /**
+     * Compare the parts of two intersections.
+     * @return a boolean result for equivalence
+     */
+    public boolean equals(Object o) {
+	return (o instanceof Intersection)
+	    &&  parts.equals(((Intersection)o).parts);
+    }
+
+    /**
+     * 
+     * @return a unique hashcode base on the parts of the intersection.
+     */
+    public int hashCode() { return parts.hashCode(); }
+
+    /**
+     * Converts the intersection into a human readable form. Expressions
+     * are separated using a '^' symbol to represent an intersection.
+     *
+     * @return formatted string representation of an intersection
+     */
+    public String toString() {
+	Iterator i = getParts();
+	StringBuffer buff = new StringBuffer();
+
+	while(i.hasNext()) {
+	    buff.append(i.next().toString());
+	    if(i.hasNext())buff.append(" ^ ");
+	}
+	return buff.toString();
+    }
+      
+	    
+
+}
+
+
+
+
Index: fedd/abac-src/rbtm/credential/LinkedRole.java
===================================================================
--- fedd/abac-src/rbtm/credential/LinkedRole.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/LinkedRole.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,103 @@
+/*
+ * LinkedRole.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+import java.util.*;
+
+/**
+ * Represent a LinkedRole.
+ */
+public class LinkedRole implements EntityExpression
+{
+    private Role        firstRole;
+    private RoleName    secondName;
+
+	public LinkedRole(Role r, RoleName n) { firstRole = r;  secondName = n; }
+
+	public LinkedRole(Role r, String n) { 
+		firstRole = r;
+		secondName = new SimpleRoleName(n);
+	}
+
+	public LinkedRole(Entity issuer, String n1, String n2) {
+		firstRole = new Role(issuer, n1);
+		secondName = new SimpleRoleName(n2);
+	}
+
+	public LinkedRole(String issuer, String n1, String n2) {
+		firstRole = new Role(issuer, n1);
+		secondName = new SimpleRoleName(n2);
+	}
+
+    public int hashCode() {  
+        return firstRole.hashCode() * 2 + secondName.hashCode();
+    }
+
+    public boolean equals(Object o) {
+        return (o instanceof LinkedRole) 
+               && firstRole.equals(((LinkedRole)o).firstRole)
+               && secondName.equals(((LinkedRole)o).secondName);
+    }
+
+    public String toString() {
+        return firstRole.toString() + "." + secondName.toString();
+    }
+
+    public Role getFirstRole() {
+        return firstRole;
+    }
+
+    public RoleName getSecondRoleName() {
+        return secondName;
+    }
+    //public Entity getIssuer() { return (Entity)_names.get(0); }
+
+/*
+    public LinkedRole(String[] strs) {
+        _names = new ArrayList();
+        _names.add(new Entity(strs[0]));
+        for (int i=1; i<strs.length; i++) {
+            _names.add(new SimpleRoleName(strs[i]));
+        }
+    }
+
+    public LinkedRole(ArrayList strs) {
+        _names = new ArrayList();
+        _names.add(new Entity((String)strs.get(0)));
+        for (int i=1; i<strs.size(); i++) {
+            _names.add(new SimpleRoleName((String) strs.get(i)));
+        }
+    }
+    public int hashCode() {
+        long value = 0;
+        for (int i=0; i<_names.size(); i++) {
+            value *= 2;
+            value += _names.get(i).hashCode();
+        }
+        return (int)value;
+    }
+    public boolean equals(Object o) 
+    {
+        return (o instanceof LinkedRole) &&
+               _names.equals(((LinkedRole)o)._names);
+    }
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append("(").append(_names.get(0));
+        for (int i=1; i<_names.size(); i++) {
+            buf.append("'s ").append(_names.get(i));
+        }
+        buf.append(")");
+        return buf.toString();
+    }
+    public RoleName getIthRoleName(int i) { return (RoleName)_names.get(i); }
+
+    public RoleName getLastRoleName() { 
+        return (RoleName)_names.get(_names.size()-1); 
+    }
+
+*/
+
+}
Index: fedd/abac-src/rbtm/credential/PermissionExpression.java
===================================================================
--- fedd/abac-src/rbtm/credential/PermissionExpression.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/PermissionExpression.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,10 @@
+
+package edu.stanford.peer.rbtm.credential;
+
+/**
+ * An EntityExpression can be: an Entity, a Role, a LinkedRole, or an Intersection.
+ * Right now, it is just a marker interface
+ */
+public interface PermissionExpression
+{
+}
Index: fedd/abac-src/rbtm/credential/RPermission.java
===================================================================
--- fedd/abac-src/rbtm/credential/RPermission.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/RPermission.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,9 @@
+/*
+ * Permission.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+public interface RPermission extends RoleName 
+{
+}
Index: fedd/abac-src/rbtm/credential/Role.java
===================================================================
--- fedd/abac-src/rbtm/credential/Role.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/Role.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,57 @@
+/*
+ * Role.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+import java.util.*;
+
+public class Role implements EntityExpression, PermissionExpression, java.io.Serializable
+{
+    private Entity    _base;
+    private RoleName  _name;
+
+    public Role(Entity e, RoleName n) { _base = e; _name = n; }
+
+	public Role(Entity e, String n) {
+		_base = e;
+		_name = new SimpleRoleName(n);
+	}
+
+    public Role(String e, String n) { 
+        _base = new SimpleEntity(e);
+        _name = new SimpleRoleName(n); 
+    }
+
+    /*
+	public Role(RoleName name) {
+		this(Entity.self, name);
+	}
+
+	public Role(String name) {
+		this(Entity.self, name);
+	}
+    */
+
+    public Entity getBase() { return _base; }
+
+    public RoleName getName() { return _name; }
+
+    public String toString() {
+        return _base.toString() + "." + _name.toString();
+    }
+
+    public int hashCode() {
+        return getBase().hashCode() * 2 + getName().hashCode();
+    }
+
+    public boolean equals(Object o) {
+        return (o instanceof Role) &&
+               getBase().equals(((Role)o).getBase()) &&
+               getName().equals(((Role)o).getName());
+    }
+
+	public boolean isPermission() {
+		return _name instanceof RPermission;
+	}
+}
Index: fedd/abac-src/rbtm/credential/RoleExpression.java
===================================================================
--- fedd/abac-src/rbtm/credential/RoleExpression.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/RoleExpression.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,10 @@
+
+package edu.stanford.peer.rbtm.credential;
+
+/**
+ * An RoleExpression can be: an Entity, a Role, a LinkedRole, or an Intersection.
+ * Right now, it is just a marker interface
+ */
+public interface RoleExpression
+{
+}
Index: fedd/abac-src/rbtm/credential/RoleName.java
===================================================================
--- fedd/abac-src/rbtm/credential/RoleName.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/RoleName.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,10 @@
+/*
+ * RoleName.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+public interface RoleName extends java.io.Serializable, Comparable
+{
+    String getName();
+}
Index: fedd/abac-src/rbtm/credential/SimpleEntity.java
===================================================================
--- fedd/abac-src/rbtm/credential/SimpleEntity.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/SimpleEntity.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,49 @@
+/*
+ * Entity.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+import java.io.*;
+//import java.security.*;
+
+/**
+ * An object of the Entity class represents an entity (or a principal) in RBTM.
+ */
+public class SimpleEntity implements Entity
+{
+    private String    _name;
+
+    public SimpleEntity(String n) 
+    { 
+        _name = n; 
+/* 
+        // code to gegerate public key
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
+        SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
+
+        keyGen.initialize(1024, random);
+
+        KeyPair pair = keyGen.generateKeyPair();
+        PrivateKey priv = pair.getPrivate();
+        PublicKey pub = pair.getPublic();
+*/
+    }
+
+    public String getName()     { return _name; }
+
+    public String toString()     { return _name;  }
+
+    public int hashCode()         { return _name.hashCode(); }
+
+    public boolean equals(Object o) {
+        return ((o instanceof SimpleEntity) 
+		       && _name.equals(((SimpleEntity)o)._name));
+    }
+
+    public int compareTo(Object o) {
+        return _name.compareTo(((SimpleEntity)o)._name);
+    }
+
+    //public java.security.PublicKey getPublicKey() { return null; }
+}
Index: fedd/abac-src/rbtm/credential/SimpleRoleName.java
===================================================================
--- fedd/abac-src/rbtm/credential/SimpleRoleName.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/SimpleRoleName.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,27 @@
+/*
+ * RoleName.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+public class SimpleRoleName implements RoleName
+{
+    private String _name;
+
+    public SimpleRoleName(String n)   { _name = n; }
+
+    public String getName()     { return _name; }
+
+    public String toString()    { return _name; }
+
+    public int hashCode()       { return _name.hashCode(); }
+
+    public boolean equals(Object o) {
+        return (o instanceof SimpleRoleName) 
+		      && _name.equals(((SimpleRoleName)o)._name);
+    }
+
+	public int compareTo(Object o) {
+		return _name.compareTo(((SimpleRoleName)o)._name);
+	}
+}
Index: fedd/abac-src/rbtm/credential/StaticCredential.java
===================================================================
--- fedd/abac-src/rbtm/credential/StaticCredential.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/StaticCredential.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,138 @@
+/*
+ * StaticCredential.java
+ */
+
+package edu.stanford.peer.rbtm.credential;
+
+import  edu.stanford.peer.rbtm.util.*;
+import java.util.*;
+
+/**
+ * StaticCredential 
+ */
+public class StaticCredential extends Credential
+{
+    private Role      role;
+    private EntityExpression subject;
+
+    public StaticCredential(Role r, EntityExpression s) { 
+        role = r;  
+        subject = s; 
+    }
+    public StaticCredential(String str) 
+	throws CredentialParsingException {
+	StringTokenizer st = new StringTokenizer(str, "<-");
+	//Debug.debugInfo("StaticCredential: cred string " + str + 
+	//		" contains " + st.countTokens() + " tokens");
+	String lhs = st.nextToken().trim();
+	String rhs = st.nextToken().trim();
+	//Debug.debugInfo("StaticCredential: lhs = " + lhs);
+	//Debug.debugInfo("StaticCredential: rhs = " + rhs);
+	role = (Role)getRole(lhs);
+	subject = getEntityExpression(rhs);
+    }
+
+    public StaticCredential(Entity issuer, RoleName n, EntityExpression s) { 
+        role = new Role(issuer, n);
+        subject = s; 
+    }
+
+    public StaticCredential(String e, String rn, String es) 
+                    throws CredentialParsingException  
+    {
+        role = new Role(new SimpleEntity(e), new SimpleRoleName(rn));
+        subject = StaticCredential.getEntityExpression(es);
+    }
+
+    public Entity getIssuer()       { return role.getBase(); }
+
+    //public Role   getRole()         { return role; }
+
+    public Role   getDefinedRole()         { return role; }
+
+    public EntityExpression getSubject()   { return subject; }
+
+    public String toString() {
+        return role.toString() + "<-" + subject.toString();
+    }
+
+    public String toXML() {
+	StringBuffer buff = new StringBuffer("<Credential ");
+	buff.append(" definedRole=\"").append(role).append("\"");
+	buff.append(" subject=\"").append(subject).append("\"");
+	buff.append("/>\n");
+	return buff.toString();
+    }
+
+    public int hashCode() {
+        return role.hashCode() * 2 + subject.hashCode();
+    }
+
+    public boolean equals(Object o) 
+    {
+        return (o instanceof StaticCredential) &&
+               role.equals(((StaticCredential)o).role) &&
+               subject.equals(((StaticCredential)o).subject);
+    }
+
+    public static EntityExpression getRole(String str) 
+	throws CredentialParsingException {
+	EntityExpression expr = null;
+	StringTokenizer st = new StringTokenizer(str.trim(), ".");
+	int count = st.countTokens();
+	String error = null;
+	
+	if(count <= 0) {
+	    error = "Role expression contained one or less parts!";
+	}
+	else if(count == 2) {
+	    expr = (EntityExpression) new Role(st.nextToken(), st.nextToken());
+	}
+	else if(count == 3) {
+	    expr = (EntityExpression)
+		new LinkedRole(st.nextToken(),st.nextToken(), st.nextToken());
+	}
+	else {
+	    error = "Role " + str + " expression contained too many role names";
+	}
+	if(expr == null) {
+	    throw new CredentialParsingException(error);
+	}
+	return expr;
+    }
+
+    /** creates a new Intersection from a string */
+    public static Intersection getIntersection(String str) 
+	throws CredentialParsingException {
+	StringTokenizer st = new StringTokenizer(str, "^");
+	int count = st.countTokens();
+	Intersection i = new Intersection();
+
+	for(int j = 0; j < count; j++) {
+	    i.and(getEntityExpression(st.nextToken()));
+	}
+	return i;
+    }
+
+    /** creates a new SimpleEntity instance from a string */
+    public static Entity getEntity(String str) 
+	throws CredentialParsingException {
+	return new SimpleEntity(str.trim());
+    }
+
+    /**
+     * converts a String into an EntityExpression, deals with Entity, Role,  
+     * LinkedRole, and Intersection. This method uses helper functions for
+     * parsiing entities, roles, and intersections, so these methods may be
+     * overridden in subclassing implementations.
+     */
+    public static EntityExpression getEntityExpression(String str) 
+	throws CredentialParsingException {
+	if(str.indexOf("^") > 0)
+	    return (EntityExpression)getIntersection(str);
+	if(str.indexOf(".") > 0)
+	    return getRole(str);
+	return (EntityExpression)getEntity(str);
+    }
+
+}
Index: fedd/abac-src/rbtm/credential/package.html
===================================================================
--- fedd/abac-src/rbtm/credential/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/credential/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,4 @@
+<BODY>
+<P>A package containing data types for representing credentials of types I-IV. 
+</P>
+</BODY>
Index: fedd/abac-src/rbtm/doc/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/doc/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/doc/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+D
Index: fedd/abac-src/rbtm/doc/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/doc/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/doc/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/doc
Index: fedd/abac-src/rbtm/doc/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/doc/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/doc/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/engine/AbstractProofNode.java
===================================================================
--- fedd/abac-src/rbtm/engine/AbstractProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/AbstractProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,341 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * The parent class of all proof nodes. This is the base class which contains
+ * default implementations of all common methods.
+ */
+public abstract class AbstractProofNode implements ProofNode
+{
+    // The following two fields can't be changed by other classes.  
+    // If subclasses need to access them, use get methods
+
+    /** 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;
+
+    /** Processing mode for subclassed node types */
+    public final boolean addRole = true;
+    
+    /** Nodes that can reach this node directly, evidences are credentials. */
+    protected ResultEvidenceMap  parents;
+
+    /** Nodes that this node can reach directly, evidecens are credentials. */
+    protected ResultEvidenceMap  children; 
+
+	/** Backward solutions on this node  */
+    protected ResultEvidenceMap  backwardSolutions;
+
+	/** Forward solutions on this node */
+    protected ResultEvidenceMap  forwardSolutions;
+
+    protected ArrayList  backwardListeners;
+    protected ArrayList  forwardListeners;
+
+    boolean backwardProcessed;
+    boolean forwardProcessed;
+
+    AbstractProofNode (ProofGraph graph, EntityExpression re, int trackType)
+    {
+	_graph = graph;
+	_roleExp = re;
+        Debug.debugInfo("A new node is created for " + re);
+
+        parents = new ResultEvidenceMap(trackType);  
+        children = new ResultEvidenceMap(trackType); 
+        backwardSolutions = new ResultEvidenceMap(trackType);
+	forwardSolutions = new ResultEvidenceMap(trackType);
+	
+	backwardListeners = new ArrayList(10);
+	forwardListeners = new ArrayList(10);
+    }
+
+    public ProofGraph getGraph() {
+	return _graph;
+    }
+    
+    public EntityExpression getRoleExp() {
+	return _roleExp;
+    }
+    
+    public ResultEvidenceMap getForwardSolutions() {
+	return forwardSolutions;
+    }
+    
+    public ResultEvidenceMap getBackwardSolutions() {
+	return backwardSolutions;
+    }
+    
+    public ResultEvidenceMap getChildren() {
+	return children;
+    }
+    
+    public ResultEvidenceMap getParents() {
+	return parents;
+    }
+    
+    /** 
+     * A single iteration of evidence gathering. This recursive method is 
+     * polymorphic and may be extended in child proof node implementations. 
+     * @param size the size of the evidence set (of credentials)
+     * @param target the parent expression to be found in the cred graph
+     */
+    public HashSet getChain(int size, EntityExpression target) {
+	return new HashSet(size);
+    }
+
+
+    public void invalidateForward() {
+    	Debug.debugInfo("Invalidate forward result on " + this);
+    	if(forwardProcessed) {
+	    forwardProcessed = false;
+	    //reuse the credential and update the forward search
+	    getGraph().addForwardNode(getRoleExp());
+	}
+    }
+
+    public void invalidateBackward() {
+    	Debug.debugInfo("Invalidate backward result on " + this);
+    	if(backwardProcessed) {
+	    backwardProcessed = false;
+	    //reuse the credential and update the backward search
+	    getGraph().addBackwardNode(getRoleExp());
+	}
+    }
+
+    public void backwardProcess() {
+	if (backwardProcessed) { return; }
+	Predicate p = getGraph().getPredicate();
+	EntityExpression expr = getRoleExp();
+	Debug.debugInfo("Backward processing " + this);
+	if(p == null) {	// cred mgr has null predicate
+	    // backwards compatibility for credential manager
+	    backwardSolutionAdded(this, expr);
+	    additionalBackwardProcess();
+	}
+	else {
+	    if(p.test(expr)) { 
+		// add this expression to the soln and stop
+		backwardSolutionAdded(this, expr);
+	    } else {	
+		// skip this soln and continue processing 
+		additionalBackwardProcess();
+	    }
+	}
+	backwardProcessed = true;
+    }
+    
+    // The method that does the work when we visit a node
+    public void forwardProcess() 
+    {
+	if (forwardProcessed) {
+	    return;
+	}
+	
+        // first step: go over all credentials that have this as subject
+        Debug.debugInfo("Forward processing " + this);
+        Iterator  credIt = _graph.findCredentialsBySubject(_roleExp);
+        while (credIt.hasNext()) { 
+            StaticCredential credential = (StaticCredential) credIt.next();
+            Debug.debugInfo("Find one credential: " + credential);
+            ProofNode node = _graph.addForwardNode(credential.getDefinedRole());
+	    node.addParent(this, credential);
+            //_graph.addProofEdge(this, node, credential);
+        }
+	
+		  additionalForwardProcess();
+		  forwardProcessed = true;
+		  
+		  // second step: find partial solutions which match this node's
+		  //              role expression, unless its an intersection
+		  if (_roleExp instanceof Intersection) { return;	}
+		  credIt = _graph.findCredentialsByPartialSubject(_roleExp);
+		  while (credIt.hasNext()) { 
+				StaticCredential credential = (StaticCredential) credIt.next();
+				ProofNode node = _graph.addForwardNode(credential.getSubject());
+				node.backwardProcess();
+				// Forward discovery of roles
+				//
+				// This is not reuired according to the algorithm from 
+				// "Distributed Credential Chain Discovery in Trust Management" 
+				// in JCS but is needed for credential discovery in ATN where 
+				// forward search takes place from sensitive roles.
+				node.forwardProcess();
+				//int j = 
+				//((Intersection) credential.getSubject()).getIndexOf(_roleExp);
+				//forward.solutionAdded(new PartialSolution(_roleExp, j));
+		  }
+    }
+    
+    abstract protected void additionalForwardProcess();
+    abstract protected void additionalBackwardProcess();
+    
+    
+    public void addBackwardListener(BackwardSolutionListener sl) {
+        Debug.debugInfo(sl + " is now listening on " + this + 
+			" for backward solutions");
+        backwardListeners.add(sl);
+    	propagateBackwardSolutionsTo(sl);
+    }
+    
+    public void addForwardListener(ForwardSolutionListener sl) {
+        Debug.debugInfo(sl + " is now listening on " + this + 
+			" for forward solutions");
+        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.putResultEvidence(node.getRoleExp(), evidence)) {  
+	    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("Backward solution added to: " + this + 
+			    " from: " + s + " value: " + 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: " + this + 
+			    " from: " + s + " value: " + r);
+	    propagateForwardSolution(r);
+	}
+    }
+
+    /** propagate backward solutions to all listening nodes. */
+    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);
+    	}
+    }
+    
+    public String toString() 
+    {
+		  return "node " + _roleExp;
+    }
+    
+
+    // 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/BackwardSolution.java
===================================================================
--- fedd/abac-src/rbtm/engine/BackwardSolution.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/BackwardSolution.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,9 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+
+public interface BackwardSolution 
+{ 
+}
+
+
Index: fedd/abac-src/rbtm/engine/BackwardSolutionListener.java
===================================================================
--- fedd/abac-src/rbtm/engine/BackwardSolutionListener.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/BackwardSolutionListener.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,8 @@
+package edu.stanford.peer.rbtm.engine;
+
+public interface BackwardSolutionListener
+{
+    // A new solution r is added to Node s
+    void backwardSolutionAdded(ProofNode source, BackwardSolution solution);
+}
+
Index: fedd/abac-src/rbtm/engine/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/engine/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,23 @@
+/AbstractProofNode.java/1.10/Tue Aug 12 19:48:29 2003//
+/BackwardSolution.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/BackwardSolutionListener.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/CredentialManager.java/1.6/Tue Aug 12 17:53:23 2003//
+/DefaultSolutionFilter.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/EntityProofNode.java/1.5/Tue Aug 12 17:55:37 2003//
+/ForwardSolution.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/ForwardSolutionListener.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/GraphEngine.java/1.11/Tue Aug 12 17:53:23 2003//
+/IntersectionProofNode.java/1.6/Fri Aug  8 19:26:07 2003//
+/LinkedRoleProofNode.java/1.5/Mon Jul 29 21:59:35 2002//
+/Oppo.java/1.2/Fri Dec 21 22:49:43 2001//
+/PartialSolutionMap.java/1.1/Fri Aug  8 19:26:07 2003//
+/ProofGraph.java/1.6/Tue Aug 12 17:54:22 2003//
+/ProofNode.java/1.4/Mon Jul 29 21:59:35 2002//
+/ProofQueue.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/RoleProofNode.java/1.7/Fri Aug  8 19:26:07 2003//
+/Sens.java/1.3/Tue Mar  5 18:30:52 2002//
+/Simp.java/1.2/Fri Dec 21 22:49:43 2001//
+/SimpleProofQueue.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/SolutionFilter.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/package.html/1.2/Tue Dec 18 01:38:12 2001//
+D
Index: fedd/abac-src/rbtm/engine/CVS/Entries.Log
===================================================================
--- fedd/abac-src/rbtm/engine/CVS/Entries.Log	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/CVS/Entries.Log	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+A D/old////
Index: fedd/abac-src/rbtm/engine/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/engine/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/engine
Index: fedd/abac-src/rbtm/engine/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/engine/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/engine/CredentialManager.java
===================================================================
--- fedd/abac-src/rbtm/engine/CredentialManager.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/CredentialManager.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,320 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.RBTMConstants;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * A graph engine is a proof graph which may optionally contain a predicate
+ * function. This implementation is a tightly coupled directed credential
+ * graph and credential index. 
+ *
+ * @deprecated 
+ */
+public class CredentialManager 
+    implements java.io.Serializable, ProofGraph, RBTMConstants
+{
+    static final public Iterator emptyIt = new ArrayList(1).iterator();
+    static final public Collection emptyCollection = new ArrayList(1);
+
+    /** stores all the credentials */
+    private HashSet credentials = new HashSet();
+
+    /** an index from issuers to credential collections */
+    private HashMap indexByIssuer = new HashMap();
+
+    /** an index from roles to credential collections */
+    private HashMap indexByRole = new HashMap();
+
+    /** an index from subjects to collections of credentials */
+    private HashMap indexBySubject = new HashMap();
+
+    /** predicate function which could be null */
+    private Predicate pred = null;
+
+	private int track;
+
+	private SolutionFilter solutionFilter;
+
+	// a proof queue
+	transient private ProofQueue proofQueue = new SimpleProofQueue();
+
+	transient private HashMap    nodeTable = new HashMap();
+
+	public CredentialManager(Set credSet, int trackType, 
+							 SolutionFilter solFilter) 
+	{
+		this(trackType, solFilter);
+		addCredentials(credentials);
+	}
+
+	public CredentialManager(int trackType, SolutionFilter solFilter) {
+		track = trackType;
+		solutionFilter = solFilter;
+	}
+
+	public CredentialManager() {
+		this(TRACK_NONE, new DefaultSolutionFilter());
+	}
+
+	public void reinit() {
+		proofQueue = new SimpleProofQueue();
+		nodeTable = new HashMap();
+	}
+
+	synchronized public void addCredentials(Collection credentials) {
+		reinit();
+		Iterator credIt = credentials.iterator();
+		while (credIt.hasNext()) {
+			addCredential((StaticCredential)credIt.next());
+		}
+	}
+
+	synchronized public void removeCredentials(Collection credentials) {
+		reinit();
+		Iterator credIt = credentials.iterator();
+		while (credIt.hasNext()) {
+			removeCredential((StaticCredential)credIt.next());
+		}
+	}
+
+    synchronized public boolean addCredential(StaticCredential cred) {
+        // Make sure that no duplicate Credential exists
+        if (credentials.contains(cred)) {
+	        Debug.debugInfo("trying to add existing credential: " + cred);
+            return false;
+        }
+        Debug.debugInfo("adding credential: " + cred);
+        credentials.add(cred);
+		addIndexFor(cred);
+		ProofNode node = getNode(cred.getDefinedRole());
+		if (node != null) {
+			node.invalidateBackward();
+		}
+		node = getNode(cred.getSubject());
+		if (node != null) {
+			node.invalidateForward();
+		}
+	    return true;
+    }
+
+	synchronized public void removeCredential(StaticCredential cred) {
+		if (credentials.contains(cred)) {
+			Debug.debugInfo("removing credential: " + cred);
+			reinit();
+			credentials.remove(cred);
+			removeIndexFor(cred);
+		} else {
+			Debug.debugInfo("trying to remove nonexistent credential: " + cred);
+			//// throw Exception
+		}
+	}
+
+	private void addIndexFor(StaticCredential cred) 
+	{
+		Entity e = cred.getIssuer();
+		ArrayList credList = (ArrayList)indexByIssuer.get(e);
+		if (credList == null) {
+			credList = new ArrayList(40);
+			indexByIssuer.put(e, credList);
+		}
+		credList.add(cred);
+
+        // Code to deal with indexByRole
+        Role r = cred.getDefinedRole();
+        credList = (ArrayList) indexByRole.get(r);
+        if (credList == null) {
+            credList = new ArrayList(10);
+            indexByRole.put(r, credList);
+        }
+        credList.add(cred);
+
+        EntityExpression subject = cred.getSubject();
+		  if(subject instanceof Intersection) {
+				Iterator parts = ((Intersection)subject).getParts();
+				while(parts.hasNext()) {
+					 EntityExpression partialSolution = 
+						  (EntityExpression)parts.next();
+					 credList = (ArrayList) indexBySubject.get(subject);
+					 if (credList == null) {
+						  credList = new ArrayList(10);
+						  indexBySubject.put(partialSolution, credList);
+					 }
+					 credList.add(cred);
+				}
+		  } else {
+				credList = (ArrayList) indexBySubject.get(subject);
+				if (credList == null) {
+					 credList = new ArrayList(10);
+					 indexBySubject.put(subject, credList);
+				}
+				credList.add(cred);
+		  }
+	}
+
+	private void removeIndexFor(StaticCredential cred) 
+	{
+		((ArrayList)indexByIssuer.get(cred.getIssuer())).remove(cred);
+		((ArrayList)indexByRole.get(cred.getDefinedRole())).remove(cred);
+		((ArrayList)indexBySubject.get(cred.getSubject())).remove(cred);
+	}
+
+	/*
+	public void addRole(Role role) {
+		if (! indexByRole.containsKey(role)) {
+			indexByRole.put(role, new ArrayList());
+		}
+	}
+	*/
+
+    synchronized public Collection getCredentialsIssuedBy(Entity e) {
+    	Collection credentials = (Collection)indexByIssuer.get(e);
+		if (credentials == null) {
+			return emptyCollection;
+		} else {
+    		return credentials;
+		}
+    }
+
+    synchronized public Iterator findCredentialsDefiningRole(Role r) 
+    {
+        ArrayList credList = (ArrayList) indexByRole.get(r);
+        if (credList == null) {
+            return emptyIt;
+        } else {
+            return credList.iterator();
+        }
+    }
+
+    synchronized public Iterator findCredentialsBySubject(EntityExpression subject)
+    {
+        ArrayList credList = (ArrayList) indexBySubject.get(subject);
+        if (credList == null) {
+            return emptyIt;
+        } else {
+            return credList.iterator();
+        }
+    }
+
+	 synchronized public Iterator findCredentialsByPartialSubject(EntityExpression subject) 
+	 {
+		  // Using a vector copies the arraylist so we don't remove from it
+        ArrayList credList = (ArrayList)indexBySubject.get(subject);
+        if (credList == null) {
+            return emptyIt;
+        }
+		  credList = (ArrayList)credList.clone();
+		  Iterator i = credList.iterator(); 
+		  while(i.hasNext()) {	// remove credential which aren't intersections
+				StaticCredential cred = (StaticCredential)i.next();
+				if(!(cred.getSubject() instanceof Intersection)) {
+					 i.remove();
+				}
+		  }
+		  return credList.iterator();
+	 }
+
+	/*    
+    boolean hasCredentialsForSubject(EntityExpression re) {
+        return findCredentialsBySubject(re).hasNext();
+    }
+	*/
+
+    // Find out all Roles that roleExp belongs to
+    synchronized public ResultEvidenceMap forwardSearch(EntityExpression roleExp) {
+        ProofNode goalNode = addForwardNode(roleExp);
+        while (proofQueue.hasUnexploredForwardNodes()) {
+            proofQueue.nextUnexploredForwardNode().forwardProcess();
+        }
+        return goalNode.getForwardSolutions();
+    }
+
+    // Find out all members of roleExp
+    synchronized public ResultEvidenceMap backwardSearch(EntityExpression roleExp) {
+        ProofNode goalNode = addBackwardNode(roleExp);
+        while (proofQueue.hasUnexploredBackwardNodes()) {
+            proofQueue.nextUnexploredBackwardNode().backwardProcess();
+        }
+        return goalNode.getBackwardSolutions();
+    }
+
+    public ProofNode addForwardNode(EntityExpression roleExp) {
+        ProofNode node = addNode(roleExp);
+        proofQueue.addForwardNode(node);
+        return node;
+    }
+
+    public ProofNode addBackwardNode (EntityExpression roleExp) {
+        ProofNode node = addNode(roleExp);
+        proofQueue.addBackwardNode(node);
+        return node;
+    }
+
+    /**
+     * Add a node corresponding to a role expression, make sure that the 
+     * node is not added twice.
+     */
+    private ProofNode addNode (EntityExpression roleExp) {
+        ProofNode node = (ProofNode)nodeTable.get(roleExp);
+        if (node == null) {
+            node = createProofNode(roleExp);
+            nodeTable.put(roleExp, node);
+        }
+        return node;
+    }
+
+	private ProofNode getNode(EntityExpression roleExp) {
+        return (ProofNode)nodeTable.get(roleExp);
+    }
+
+    private ProofNode createProofNode (EntityExpression roleExp) {
+        if (roleExp instanceof Role) {
+            return new RoleProofNode(this, (Role)roleExp, track);
+        } else if (roleExp instanceof LinkedRole) {
+            return new LinkedRoleProofNode(this, (LinkedRole)roleExp, track);
+        } else if (roleExp instanceof Intersection) {
+            return new IntersectionProofNode(this,(Intersection)roleExp,track);
+        } else {
+            return new EntityProofNode(this, (Entity)roleExp, track);
+        }
+    }
+
+    public ForwardSolution getForwardSolution(EntityExpression re) {
+		return solutionFilter.getForwardSolution(re);
+    }
+
+    public BackwardSolution getBackwardSolution(EntityExpression re) {
+	    return solutionFilter.getBackwardSolution(re);
+    }
+
+    public String toString() {
+        return "credentials=" + credentials.toString() + "\n" +
+			   "indexByIssuer=" + indexByIssuer.toString() + "\n" +
+               "indexByRole=" + indexByRole.toString() + "\n" +
+    		   "indexBySubject=" + indexBySubject.toString();
+    }
+	
+	private String getSubjectIndexs()
+	{
+		StringBuffer outBuf = new StringBuffer();
+		Iterator keyIt = indexBySubject.keySet().iterator();
+		while (keyIt.hasNext()) {
+			Object o = keyIt.next();
+			if (o instanceof Role) {
+				outBuf.append("Role ").append(o.toString()).append("\n");
+				Role r = (Role) o;
+				outBuf.append("Base is ").append(r.getBase().getClass()).append("\n");
+				outBuf.append("RoleName is ").append(r.getName().getClass()).append("\n");
+			}
+		}
+		return outBuf.toString();
+	}
+
+    public HashSet getChain(EntityExpression source, EntityExpression target) {
+        return new HashSet();
+    }
+    
+    public Predicate getPredicate() { return pred; }
+}
Index: fedd/abac-src/rbtm/engine/DefaultSolutionFilter.java
===================================================================
--- fedd/abac-src/rbtm/engine/DefaultSolutionFilter.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/DefaultSolutionFilter.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,26 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+
+public class DefaultSolutionFilter implements SolutionFilter, java.io.Serializable
+{
+	public ForwardSolution getForwardSolution(EntityExpression re) {
+		if (re instanceof Role) {
+			return re;
+		}
+		return null;
+	}
+
+	public BackwardSolution getBackwardSolution(EntityExpression re) {
+		if (re instanceof Entity) {
+			return re;
+		}
+		return null;
+	}
+}
+
+
+
+
+
+
Index: fedd/abac-src/rbtm/engine/EntityProofNode.java
===================================================================
--- fedd/abac-src/rbtm/engine/EntityProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/EntityProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,56 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+/**
+ * A proof node which respresents an entity in the credential graph.
+ */
+public class EntityProofNode extends AbstractProofNode
+{
+	/**
+	 * A map for managing all the partial solutions per intersection that arrive
+	 */
+   static protected PartialSolutionMap partialSolutions = 
+		 new PartialSolutionMap();
+
+	/**
+	 * Default constructor
+	 */
+   protected EntityProofNode(ProofGraph graph, Entity re, int trackType) {
+		 super(graph, re, trackType);
+	}
+	
+	public void additionalBackwardProcess() {
+	    //backwardSolutionAdded(this, getRoleExp());
+	}
+
+	public void additionalForwardProcess() {
+	    
+	}
+	 
+	/**
+	 * Adds a forward solution but propagating the solution backwards along
+	 * the credential chain. If s is a partial solution and all k pieces have
+	 * arrived, then add edge from this node to the intersection.
+	 */
+	public void forwardSolutionAdded(ProofNode s, ForwardSolution r) {
+		 super.forwardSolutionAdded(s, r);
+		 EntityExpression expr = s.getRoleExp();
+		 System.out.println("Additional forward processing on " + getRoleExp() +
+								  " where s = " + expr);
+		 Iterator iCreds = getGraph().findCredentialsByPartialSubject(expr);
+		 while(iCreds.hasNext()) { // if s is partial solution of intersection(s)
+			  StaticCredential credential = (StaticCredential) iCreds.next();
+			  Intersection i = (Intersection)credential.getSubject();				
+			  System.out.println(getRoleExp() + " matches partial solution " + i);
+			  if(partialSolutions.addPartialSolution(i, expr)) {
+					ProofNode node = getGraph().addForwardNode(i);
+					node.addParent(node, r);
+			  }
+		 } 
+	}
+
+	 
+}   
+
+
Index: fedd/abac-src/rbtm/engine/ForwardSolution.java
===================================================================
--- fedd/abac-src/rbtm/engine/ForwardSolution.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/ForwardSolution.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,6 @@
+package edu.stanford.peer.rbtm.engine;
+
+public interface ForwardSolution 
+{ 
+}
+
Index: fedd/abac-src/rbtm/engine/ForwardSolutionListener.java
===================================================================
--- fedd/abac-src/rbtm/engine/ForwardSolutionListener.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/ForwardSolutionListener.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,8 @@
+package edu.stanford.peer.rbtm.engine;
+
+public interface ForwardSolutionListener
+{
+    // A new solution r is added to Node s
+    void forwardSolutionAdded(ProofNode source, ForwardSolution solution);
+}
+
Index: fedd/abac-src/rbtm/engine/GraphEngine.java
===================================================================
--- fedd/abac-src/rbtm/engine/GraphEngine.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/GraphEngine.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,370 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.RBTMConstants;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * A graph engine is a proof graph which may optionally contain a predicate
+ * function. This implementation is a tightly coupled directed credential
+ * graph and credential index. 
+ */
+public class GraphEngine
+    implements java.io.Serializable, ProofGraph, RBTMConstants
+{
+    static final public Iterator emptyIt = new ArrayList(1).iterator();
+    static final public Collection emptyCollection = new ArrayList(1);
+
+    /** stores all the credentials */
+    private HashSet credentials = new HashSet();
+
+    /** an index from issuers to credential collections */
+    private HashMap indexByIssuer = new HashMap();
+
+    /** an index from roles to credential collections */
+    private HashMap indexByRole = new HashMap();
+
+    /** an index from role name to credential collections */
+    private HashMap indexByRoleName = new HashMap();
+
+    /** an index from subjects to collections of credentials */
+    private HashMap indexBySubject = new HashMap();
+
+    /** predicate function which could be null */
+    private Predicate pred = null;
+
+    private int track;
+    
+    private SolutionFilter solutionFilter;
+
+    // a proof queue
+    transient private ProofQueue proofQueue = new SimpleProofQueue();
+    
+    transient private HashMap    nodeTable = new HashMap();
+
+
+    public GraphEngine(Set creds, int tt, SolutionFilter filter, Predicate p) {
+	this(creds, tt, filter);
+	pred = p;
+    }
+    
+    public GraphEngine(Set creds, int trackType, SolutionFilter filter)
+    {
+	this(trackType, filter);
+	addCredentials(creds);
+    }
+
+    public GraphEngine(int trackType, SolutionFilter filter) {
+	track = trackType;
+	solutionFilter = (filter == null)? new DefaultSolutionFilter(): filter;
+    }
+
+    public GraphEngine(Predicate p) {
+	this();
+	pred = p;
+    }
+
+    public GraphEngine() {
+	this(TRACK_ALL, null);
+    }
+    
+
+	public void reinit() {
+		proofQueue = new SimpleProofQueue();
+		nodeTable = new HashMap();
+	}
+
+	synchronized public void addCredentials(Collection credentials) {
+		reinit();
+		Iterator credIt = credentials.iterator();
+		while (credIt.hasNext()) {
+			addCredential((StaticCredential)credIt.next());
+		}
+	}
+
+	synchronized public void removeCredentials(Collection credentials) {
+		reinit();
+		Iterator credIt = credentials.iterator();
+		while (credIt.hasNext()) {
+			removeCredential((StaticCredential)credIt.next());
+		}
+	}
+
+    synchronized public boolean addCredential(StaticCredential cred) {
+        // Make sure that no duplicate Credential exists
+        if (credentials.contains(cred)) {
+	        Debug.debugInfo("trying to add existing credential: " + cred);
+            return false;
+        }
+        Debug.debugInfo("adding credential: " + cred);
+        credentials.add(cred);
+		addIndexFor(cred);
+		ProofNode node = getNode(cred.getDefinedRole());
+		if (node != null) {
+			node.invalidateBackward();
+		}
+		node = getNode(cred.getSubject());
+		if (node != null) {
+			node.invalidateForward();
+		}
+	    return true;
+    }
+
+	synchronized public void removeCredential(StaticCredential cred) {
+		if (credentials.contains(cred)) {
+			Debug.debugInfo("removing credential: " + cred);
+			reinit();
+			credentials.remove(cred);
+			removeIndexFor(cred);
+		} else {
+			Debug.debugInfo("trying to remove nonexistent credential: " + cred);
+			//// throw Exception
+		}
+	}
+
+	private void addIndexFor(StaticCredential cred) 
+	{
+		Entity e = cred.getIssuer();
+		ArrayList credList = (ArrayList)indexByIssuer.get(e);
+		if (credList == null) {
+			credList = new ArrayList(40);
+			indexByIssuer.put(e, credList);
+		}
+		credList.add(cred);
+
+        // Code to deal with indexByRole
+        Role r = cred.getDefinedRole();
+        credList = (ArrayList) indexByRole.get(r);
+        if (credList == null) {
+            credList = new ArrayList(10);
+            indexByRole.put(r, credList);
+        }
+        credList.add(cred);
+
+        // Code to deal with indexByRoleName
+        RoleName name = r.getName();
+        credList = (ArrayList) indexByRoleName.get(name);
+        if (credList == null) {
+            credList = new ArrayList(10);
+            indexByRoleName.put(name, credList);
+        }
+        credList.add(cred);
+
+        EntityExpression subject = cred.getSubject();
+		  if(subject instanceof Intersection) {
+				Iterator parts = ((Intersection)subject).getParts();
+				while(parts.hasNext()) {
+					 EntityExpression partialSolution = 
+						  (EntityExpression)parts.next();
+					 credList = (ArrayList) indexBySubject.get(subject);
+					 if (credList == null) {
+						  credList = new ArrayList(10);
+						  indexBySubject.put(partialSolution, credList);
+					 }
+					 credList.add(cred);
+				}
+		  } else {
+				credList = (ArrayList) indexBySubject.get(subject);
+				if (credList == null) {
+					 credList = new ArrayList(10);
+					 indexBySubject.put(subject, credList);
+				}
+				credList.add(cred);
+		  }
+    }
+
+	private void removeIndexFor(StaticCredential cred) 
+	{
+		((ArrayList)indexByIssuer.get(cred.getIssuer())).remove(cred);
+		((ArrayList)indexByRole.get(cred.getDefinedRole())).remove(cred);
+		((ArrayList)indexBySubject.get(cred.getSubject())).remove(cred);
+	}
+
+	/*
+	public void addRole(Role role) {
+		if (! indexByRole.containsKey(role)) {
+			indexByRole.put(role, new ArrayList());
+		}
+	}
+	*/
+
+	 /**
+	  * Repository function: finds all credentials issued by entity e.
+	  */
+    synchronized public Collection getCredentialsIssuedBy(Entity e) {
+    	Collection credentials = (Collection)indexByIssuer.get(e);
+		if (credentials == null) {
+			return emptyCollection;
+		} else {
+    		return credentials;
+		}
+    }
+
+
+    synchronized public Iterator findCredentialsDefiningRole(RoleName r) 
+    {
+        ArrayList credList = (ArrayList) indexByRoleName.get(r);
+        if (credList == null) {
+            return emptyIt;
+        } else {
+            return credList.iterator();
+        }
+    }
+
+    synchronized public Iterator findCredentialsDefiningRole(Role r) 
+    {
+        ArrayList credList = (ArrayList) indexByRole.get(r);
+        if (credList == null) {
+            return emptyIt;
+        } else {
+            return credList.iterator();
+        }
+    }
+
+    synchronized public Iterator findCredentialsBySubject(EntityExpression subject)
+    {
+        ArrayList credList = (ArrayList) indexBySubject.get(subject);
+        if (credList == null) {
+            return emptyIt;
+        } else {
+            return credList.iterator();
+        }
+    }
+
+	 synchronized public Iterator findCredentialsByPartialSubject(EntityExpression subject) 
+	 {
+		  // Using a vector copies the arraylist so we don't remove from it
+        ArrayList credList = (ArrayList)indexBySubject.get(subject);
+        if (credList == null) {
+            return emptyIt;
+        }
+		  credList = (ArrayList)credList.clone();
+		  Iterator i = credList.iterator(); 
+		  while(i.hasNext()) {	// remove credential which aren't intersections
+				StaticCredential cred = (StaticCredential)i.next();
+				if(!(cred.getSubject() instanceof Intersection)) {
+					 i.remove();
+					 //System.out.println("Removing " + cred.getSubject());
+				} else {
+					 //System.out.println("Not Removing " + cred.getSubject());
+				}
+		  }
+		  return credList.iterator();
+	 }
+
+	/*    
+    boolean hasCredentialsForSubject(EntityExpression re) {
+        return findCredentialsBySubject(re).hasNext();
+    }
+	*/
+
+    // Find out all Roles that roleExp belongs to
+    synchronized public ResultEvidenceMap forwardSearch(EntityExpression roleExp) {
+        ProofNode goalNode = addForwardNode(roleExp);
+        while (proofQueue.hasUnexploredForwardNodes()) {
+            proofQueue.nextUnexploredForwardNode().forwardProcess();
+        }
+        return goalNode.getForwardSolutions();
+    }
+
+    // Find out all members of roleExp
+    synchronized public ResultEvidenceMap backwardSearch(EntityExpression roleExp) {
+        ProofNode goalNode = addBackwardNode(roleExp);
+        while (proofQueue.hasUnexploredBackwardNodes()) {
+            proofQueue.nextUnexploredBackwardNode().backwardProcess();
+        }
+        return goalNode.getBackwardSolutions();
+    }
+
+    public ProofNode addForwardNode(EntityExpression roleExp) {
+        ProofNode node = addNode(roleExp);
+        proofQueue.addForwardNode(node);
+        return node;
+    }
+
+    public ProofNode addBackwardNode (EntityExpression roleExp) {
+        ProofNode node = addNode(roleExp);
+        proofQueue.addBackwardNode(node);
+        return node;
+    }
+
+    /**
+     * Add a node corresponding to a role expression, make sure that the 
+     * node is not added twice.
+     */
+    private ProofNode addNode (EntityExpression roleExp) {
+        ProofNode node = (ProofNode)nodeTable.get(roleExp);
+        if (node == null) {
+            node = createProofNode(roleExp);
+            nodeTable.put(roleExp, node);
+        }
+        return node;
+    }
+
+    private ProofNode getNode(EntityExpression roleExp) {
+        return (ProofNode)nodeTable.get(roleExp);
+    }
+
+    private ProofNode createProofNode (EntityExpression roleExp) {
+        if (roleExp instanceof Role) {
+            return new RoleProofNode(this, (Role)roleExp, track);
+        } else if (roleExp instanceof LinkedRole) {
+            return new LinkedRoleProofNode(this, (LinkedRole)roleExp, track);
+        } else if (roleExp instanceof Intersection) {
+            return new IntersectionProofNode(this,(Intersection)roleExp,track);
+        } else {
+            return new EntityProofNode(this, (Entity)roleExp, track);
+        }
+    }
+
+    public ForwardSolution getForwardSolution(EntityExpression re) {
+		return solutionFilter.getForwardSolution(re);
+    }
+
+    public BackwardSolution getBackwardSolution(EntityExpression re) {
+	    return solutionFilter.getBackwardSolution(re);
+    }
+
+    public String toString() {
+        return "credentials=" + credentials.toString() + "\n" +
+			   "indexByIssuer=" + indexByIssuer.toString() + "\n" +
+               "indexByRole=" + indexByRole.toString() + "\n" +
+    		   "indexBySubject=" + indexBySubject.toString();
+    }
+	
+	private String getSubjectIndexs()
+	{
+		StringBuffer outBuf = new StringBuffer();
+		Iterator keyIt = indexBySubject.keySet().iterator();
+		while (keyIt.hasNext()) {
+			Object o = keyIt.next();
+			if (o instanceof Role) {
+				outBuf.append("Role ").append(o.toString()).append("\n");
+				Role r = (Role) o;
+				outBuf.append("Base is ").append(r.getBase().getClass()).append("\n");
+				outBuf.append("RoleName is ").append(r.getName().getClass()).append("\n");
+			}
+		}
+		return outBuf.toString();
+	}
+    
+    public Predicate getPredicate() { return pred; }
+
+    public HashSet getChain(EntityExpression source, EntityExpression target) {
+	System.out.println("source = " + source);
+	System.out.println("target = " + target);    
+	ProofNode sourceNode = getNode(source);
+	System.out.println("node table = " + nodeTable);
+	if(sourceNode != null) {
+	    return sourceNode.getChain(0, target);
+    }
+	return null;
+    }
+    
+    /** accessor method added to support distributed discovery */
+    protected HashSet getCredentials() { return credentials; }
+}
+
+
Index: fedd/abac-src/rbtm/engine/IntersectionProofNode.java
===================================================================
--- fedd/abac-src/rbtm/engine/IntersectionProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/IntersectionProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,151 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * A credential graph node to represent an intersection. 
+ */
+public class IntersectionProofNode extends AbstractProofNode 
+{
+    /** Initial capacity for a new intersection proof node */
+    private int CAPACITY = 10;
+
+    /** 
+     * Backward solution monitor for this node.
+     * @see IntersectionMonitor
+     */
+    private IntersectionMonitor iMonitor;
+
+    /** The number sub-part expressions which belong to this intersection */
+    private int k = 0;
+
+    /**
+     * Generic constructor for creating a new intersection proof node in a
+     * credential graph.
+     * @param g The credential graph to which the node should belong
+     * @param i The intersection role expression the node represents
+     * @param type The track type used for result evidence maps
+     */
+    protected IntersectionProofNode(ProofGraph g, Intersection i, int type) {
+		  super(g, i, type);
+    }
+
+
+    public HashSet getChain(int size, EntityExpression target) {
+        Iterator parts = ((Intersection)getRoleExp()).getParts();
+        ProofGraph graph = getGraph();
+        HashSet results = new HashSet();
+
+        if(getRoleExp().equals(target)) {
+            return(new HashSet(size++));
+        }
+        while(parts.hasNext()) {
+            EntityExpression part = (EntityExpression)parts.next();
+            //System.out.println("&&&&& Getting chain from " + 
+            //part + " to " + target);
+            results.addAll(graph.getChain(part, target));
+        }
+        return results;
+    }
+
+    public void additionalBackwardProcess() {
+		  if (iMonitor != null)return;
+		  Intersection i = (Intersection)getRoleExp();
+        iMonitor = new IntersectionMonitor();
+		  Iterator parts = i.getParts();
+		  k = i.getPartsCount();
+		  while(parts.hasNext()) {
+				EntityExpression expr = (EntityExpression)parts.next();
+				ProofNode node = getGraph().addBackwardNode(expr);
+				node.addBackwardListener(iMonitor);
+				Debug.debugInfo(iMonitor.toString() + ": adding expr = " + expr );
+		  }
+    }
+
+    /**
+     * This method derives from RoleProofNode. 
+     */ 
+    public void additionalForwardProcess() {
+
+    }
+
+    /**
+     * A listener for monitoring possible backward solutions.
+     */
+    class IntersectionMonitor implements BackwardSolutionListener {
+	/**
+	 * a partial solutions map
+	 */
+	HashMap results = new HashMap(CAPACITY);
+
+	/**
+	 * Solutions are stored internally until all child nodes return a
+	 * specific solution at which time the solution is propagted to the
+	 * parent.
+	 * @param source child node which propagates the answer to its parent
+	 * @param soln an entity expression instance which is a partial sol'n
+	 */
+	public void backwardSolutionAdded(ProofNode source, BackwardSolution soln) {
+	    // list of sources for this soln
+	    SolutionCounter counter = (SolutionCounter)results.get(soln);
+	    // if this is a new solution then create a new list
+	    if(counter == null) {
+		counter = new SolutionCounter(); // use k even if k grows
+		results.put(soln, counter);      // add  new counter to table
+	    }
+	    counter.increment();
+	    if(counter.isDone()) {
+		// AbstractProofNode 
+		IntersectionProofNode.super.backwardSolutionAdded(source,soln);
+	    }
+	    else
+		Debug.debugInfo(toString() + ": part soln " + soln + " = " + 
+				counter);
+	}
+
+	/**
+	 * Creates a human readable version of ther current intersection
+	 * instance. Expression parts are separated with the '^' operator.
+	 */
+	public String toString() {
+	    return "Monitor for (" + getRoleExp() + " w/k = " + k + ")";
+	}
+
+	/**
+	 * A class to monitor the number of solution matches received 
+	 * by an intersection's proof node.
+	 */
+	class SolutionCounter { 
+	    /**
+	     * The counter integer
+	     */
+	    private int count = 0;
+	    
+	    /**
+	     * Increment the counter by one.
+	     */
+	    public void increment() { count += 1; }
+
+	    /**
+	     * A test method to see if the counter has max'ed out.
+	     *
+	     * @return true if count reaches k otherwise false.
+	     */
+	    public boolean isDone() { return (count >= k && k != 0); }
+	    
+	    /**
+	     * To see what value the counter has set.
+	     */
+	    public String toString() { return Integer.toString(count); }
+
+	}
+
+    }
+
+    
+}
+
+
Index: fedd/abac-src/rbtm/engine/LinkedRoleProofNode.java
===================================================================
--- fedd/abac-src/rbtm/engine/LinkedRoleProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/LinkedRoleProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,75 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+
+public class LinkedRoleProofNode extends AbstractProofNode
+{
+	private BackwardLinkingMonitor  monitor;
+
+    protected LinkedRoleProofNode(ProofGraph graph, LinkedRole re, int trackType) {
+		super(graph, re, trackType);
+	}
+
+
+    public HashSet getChain(int size, EntityExpression target) {
+        if(target.equals(getRoleExp())) {
+            return new HashSet(size);
+        }
+        System.out.println("\n+++++ this = " + getRoleExp());	
+        ResultEvidenceMap solutions = getBackwardSolutions();
+        HashSet soln = (HashSet)solutions.getResultEvidence(target);
+        System.out.println("solutions = " + solutions);
+        System.out.println("soln = " + soln);
+        //In the end, there can be only ONE . . . 
+        ProofNode nextNode =(ProofNode)soln.iterator().next();
+        System.out.println("\n+++++ next = " + nextNode.getRoleExp() );
+        size++;
+        HashSet set = nextNode.getChain(size, target);
+        Role aDotR1 = ((LinkedRole)getRoleExp()).getFirstRole();
+        System.out.println("\n+++++ A.r1 = " + aDotR1);
+        Entity b = ((Role)nextNode.getRoleExp()).getBase();
+        System.out.println("\n+++++ B = " + b);
+        HashSet results = 
+            getGraph().getChain((EntityExpression)aDotR1, (EntityExpression)b);
+        System.out.println("\n+++++ results  = " + results);
+        Iterator evidence = results.iterator();
+        while(evidence.hasNext()) {
+            set.add((Credential)evidence.next());
+        }
+        return set;
+    }
+
+
+    public void additionalBackwardProcess() {
+		if (monitor != null) {
+			return;
+		}
+        Role firstRole = (Role) ((LinkedRole)getRoleExp()).getFirstRole();
+        ProofNode node = getGraph().addBackwardNode(firstRole);
+        monitor = new BackwardLinkingMonitor();
+        node.addBackwardListener(monitor);
+	//if(addRole)backwardSolutionAdded(this, getRoleExp());
+    }
+
+    class BackwardLinkingMonitor implements BackwardSolutionListener {
+        public void backwardSolutionAdded(ProofNode s,  BackwardSolution re) {
+	    if (re instanceof Entity) {
+		Role  r = new Role((Entity)re, 
+		   ((LinkedRole)getRoleExp()).getSecondRoleName());
+		ProofNode node = getGraph().addBackwardNode(r);
+		node.addChild(LinkedRoleProofNode.this, s);
+	    }
+        }
+	
+	public String toString() {
+	    return "Monitor " + getRoleExp();
+	}
+    }
+
+	public void additionalForwardProcess() {
+	}
+} // End of class LinkedRoleProofNode
Index: fedd/abac-src/rbtm/engine/Oppo.java
===================================================================
--- fedd/abac-src/rbtm/engine/Oppo.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/Oppo.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,55 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+import java.util.*;
+
+/**
+ * A predicate on role expressions used by a verifier to determine if a target
+ * may be skipped over and not created.
+ */
+public class Oppo implements Predicate {
+    /** issuer-traces-all roles */
+    protected Vector issuerTraces;
+
+    /** create a new oppo predicate w/o traceable role names */
+    public Oppo() { issuerTraces = new Vector(); }
+
+    /** create a new oppo predicate with a set of traceable role names */
+    public Oppo(Vector roles) { issuerTraces = new Vector(roles); }
+
+    /** add a role name to the subject-traces-all list */
+    public void addSubject(String name) {
+	addSubject(new SimpleRoleName(name));
+    }
+
+    /** add a role name to the subject-traces-all list */
+    public void addSubject(RoleName role) {
+	issuerTraces.add(role);
+    }
+    /** add a set of role names to the subject-traces-all list */
+    public void addSubjects(Vector roles) { 
+	issuerTraces.addAll(roles); 
+    }
+
+    /** remove a role name from the subject-traces-all list */
+    public void removeSubject(String name) {
+	removeSubject(new SimpleRoleName(name));
+    }
+    
+    /** remove a role name from the subject-traces-all list */
+    public void removeSubject(RoleName role) {
+	issuerTraces.remove(role);
+    }
+
+    /** apply the predicate to determine if this role is subject-traces-all */
+    public boolean test(EntityExpression obj) {
+	if(obj instanceof Role) {
+	    Role role = (Role)obj;
+	    return (!issuerTraces.contains(role.getName()));
+	}
+	return true;
+    }
+
+}
Index: fedd/abac-src/rbtm/engine/PartialSolutionMap.java
===================================================================
--- fedd/abac-src/rbtm/engine/PartialSolutionMap.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/PartialSolutionMap.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,37 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+/**
+ * A map which keeps track of how many partial solutions reach a proof node,
+ * using a decrementing counter, which is initialized to k for each 
+ * intersection.
+ */
+public class PartialSolutionMap
+{
+	 /** table of decrementing counters, one per intersection */
+	 HashMap counters = new HashMap();
+
+	 /** get the count of outstanding partial solutions */
+	 public int getPartialSolutionCount(Intersection inter) {
+		  return ((Integer)counters.get(inter)).intValue();
+	 }
+	 
+	 /**
+	  * decrement the counter by 1 for the specified intersect, creating a 
+	  * new counter, if necessary 
+	  */
+	 public boolean addPartialSolution(Intersection inter,EntityExpression expr)
+	 {
+		  int partialSolutionCount = -1;
+		  try {
+				partialSolutionCount = getPartialSolutionCount(inter);
+		  } catch(NullPointerException nullEx) {
+				partialSolutionCount = inter.getPartsCount();
+		  } catch(Exception ex) {
+				ex.printStackTrace();
+		  }
+		  counters.put(inter, new Integer(--partialSolutionCount));
+		  return (partialSolutionCount == 0)? true: false;
+	 }
+}
Index: fedd/abac-src/rbtm/engine/ProofGraph.java
===================================================================
--- fedd/abac-src/rbtm/engine/ProofGraph.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/ProofGraph.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,44 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * The class AbstractProofGraph represents a proof graph.  It <OL>
+ * <LI> makes sure that the same node is not added more than once
+ * <LI> makes sure that the same edge is not added more than once </OL>
+ * If one wants to implement priority queue, one should extend this
+ * class.
+ */
+public interface ProofGraph extends SolutionFilter
+{
+    /** Add a node into the worklist for forward processing */
+    ProofNode addForwardNode(EntityExpression roleExp);
+	
+    /** Add a node into the worklist for backward processing */
+    ProofNode addBackwardNode (EntityExpression roleExp);
+
+    /** Search graph for credentials based on their right hand side (RHS) */
+    Iterator findCredentialsBySubject(EntityExpression re);
+
+    /** Search graph for credentials w/subject intersection matching part */
+    Iterator findCredentialsByPartialSubject(EntityExpression part);
+
+    /** Search graph for credentials based on their left hand side (LHS) */
+    Iterator findCredentialsDefiningRole(Role r);
+
+    /** Find all the members of a role expression */
+    ResultEvidenceMap backwardSearch(EntityExpression roleExp);
+
+    /** Find all the roles to which a role expression belongs */
+    ResultEvidenceMap forwardSearch(EntityExpression roleExp);
+
+    /** Public accessor method for the predicate if any for this graph. */
+    Predicate getPredicate();
+
+    /** Utility function for composing a credential chain */
+    public HashSet getChain(EntityExpression source, EntityExpression target); 
+
+}
Index: fedd/abac-src/rbtm/engine/ProofNode.java
===================================================================
--- fedd/abac-src/rbtm/engine/ProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/ProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,75 @@
+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 invalidateForward();
+
+	void invalidateBackward();
+
+	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);
+
+	ResultEvidenceMap getForwardSolutions();
+
+	ResultEvidenceMap getBackwardSolutions();
+
+        ResultEvidenceMap getParents();
+    
+        ResultEvidenceMap getChildren();
+    
+    /**
+	 * recursively travers the credential graph and collect evidence along
+	 * the way.
+	 * @return credentials from this node and further along the traversal 
+	 */
+        HashSet getChain(int size, EntityExpression target);
+
+	/**
+	 * 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/ProofQueue.java
===================================================================
--- fedd/abac-src/rbtm/engine/ProofQueue.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/ProofQueue.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,11 @@
+package edu.stanford.peer.rbtm.engine;
+
+public interface ProofQueue 
+{
+    boolean hasUnexploredForwardNodes();
+    boolean hasUnexploredBackwardNodes();
+    ProofNode nextUnexploredForwardNode();
+    ProofNode nextUnexploredBackwardNode();
+    void addForwardNode(ProofNode node);
+    void addBackwardNode(ProofNode node);
+}
Index: fedd/abac-src/rbtm/engine/RoleProofNode.java
===================================================================
--- fedd/abac-src/rbtm/engine/RoleProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/RoleProofNode.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,121 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * A proof node which represents a role in the credential graph.
+ */
+public class RoleProofNode extends AbstractProofNode
+{
+	/**
+	 * A map for managing all the partial solutions per intersection that arrive
+	 */
+   static protected PartialSolutionMap partialSolutions = 
+		 new PartialSolutionMap();
+
+   /** A forwarlinking monitor which handles linking goals */
+	private ForwardLinkingMonitor monitor;
+
+    protected RoleProofNode(ProofGraph graph, Role re, int trackType) {
+    	super(graph, re, trackType);
+    }
+
+    public HashSet getChain(int size, EntityExpression target) {
+	if(target.equals(getRoleExp())) {
+	    System.out.println("\n@@@@@ creating set of size " + size);
+	    return new HashSet(size);
+	}
+	System.out.println("\n@@@@@ this = " + getRoleExp());	
+	ResultEvidenceMap solutions = getBackwardSolutions();
+	//ProofNode nextNode =(ProofNode)solutions.getResultEvidence(target);
+	HashSet soln = (HashSet)solutions.getResultEvidence(target);
+	System.out.println("solutions = " + solutions);
+	System.out.println("soln = " + soln);
+	//In the end, there can be only ONE . . . 
+	ProofNode nextNode =(ProofNode)soln.iterator().next();
+	System.out.println("\n@@@@@ next = " + nextNode.getRoleExp() );
+	size++;
+	HashSet set = nextNode.getChain(size, target);
+	System.out.println("\n@@@@@ children  = " + nextNode.getChildren());
+        HashSet results = 
+	    (HashSet)nextNode.getChildren().getResultEvidence(getRoleExp());
+	Iterator evidence = results.iterator();
+	while(evidence.hasNext()) {
+	    set.add((Credential)evidence.next());
+	}
+	return set;
+    }
+
+    public void additionalBackwardProcess() {
+        Iterator  credIt = getGraph().findCredentialsDefiningRole((Role)getRoleExp());
+        while (credIt.hasNext()) {
+            StaticCredential credential = (StaticCredential) credIt.next();
+            ProofNode node = getGraph().addBackwardNode(credential.getSubject());
+	    node.addChild(this, credential);
+	    //if(addRole)backwardSolutionAdded(this, getRoleExp());
+        }
+    }
+
+    public void additionalForwardProcess() {
+		Role thisRole = (Role)getRoleExp();
+		// Make itself a forward solution to itself
+		forwardSolutionAdded(this, thisRole);
+		
+		if (monitor == null) {
+	        ProofNode node = getGraph().addForwardNode(thisRole.getBase());
+			monitor = new ForwardLinkingMonitor();
+	        node.addForwardListener(monitor);
+		}
+    }
+	 /**
+	  * Adds a forward solution but propagating the solution backwards along
+	  * the credential chain. If s is a partial solution and all k pieces have
+	  * arrived, then add edge from this node to the intersection.
+	  */
+	 public void forwardSolutionAdded(ProofNode s, ForwardSolution r) {
+		  EntityExpression expr = s.getRoleExp();
+		  Iterator iCreds = getGraph().findCredentialsByPartialSubject(expr);
+		  
+		  super.forwardSolutionAdded(s, r);
+		  if(iCreds.hasNext()) {  // if s is partial solution of intersection(s)
+				StaticCredential credential = (StaticCredential) iCreds.next();
+				Intersection i = (Intersection)credential.getSubject();				
+				if(partialSolutions.addPartialSolution(i, expr)) {
+					 ProofNode node = getGraph().addForwardNode(i);
+					 node.addParent(node, r);
+				}
+		  } 
+	 }
+
+    class ForwardLinkingMonitor implements ForwardSolutionListener {
+        public void forwardSolutionAdded(ProofNode s,  ForwardSolution sol) {
+			if (sol instanceof Role) {
+				Role  role = (Role)sol;
+				if (role.getName() instanceof RPermission) {
+					return;
+				}
+				LinkedRole linkedRole = 
+					 new LinkedRole(role, ((Role)getRoleExp()).getName());
+				//if (getGraph().hasCredentialsForSubject(linkedRole)) {
+				ProofNode node = getGraph().addForwardNode(linkedRole);
+				node.addParent(RoleProofNode.this, s);
+				// addProofEdge(this, node, s);
+			}
+        }
+
+	    public String toString() {
+	    	return "Monitor " + getRoleExp();
+	    }
+    }
+	
+	
+} // End of class RoleProofNode
+
+
+
+
+
+
Index: fedd/abac-src/rbtm/engine/Sens.java
===================================================================
--- fedd/abac-src/rbtm/engine/Sens.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/Sens.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,63 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+import java.util.*;
+
+/**
+ * A predicate for determining whether a credential is sensitive.
+ */
+public class Sens implements Predicate {
+
+    /** A list of sensitive credentials for this predicate */
+    protected Vector sens;
+
+    /**
+     * Create a new sens predicate with no sensitive credentials.
+     */
+    public Sens() { sens = new Vector(); }
+
+    /**
+     * Create a new sens predicate with a list of pre-defined sensitive 
+     * credentials.
+     */
+    public Sens(Vector creds) { 
+	sens = new Vector();
+	for(int i = 0; i < creds.size(); i++) {
+	    try {
+		Role r = (Role)creds.elementAt(i);
+		sens.addElement(r);
+	    }
+	    catch(Exception ex) {
+		ex.printStackTrace();
+	    }
+	}
+    }
+
+    /** Mark a credential as sensitive w/o exposing internal data structures */
+    public void addSensCred(Role role) { sens.add(role); }
+
+    /** Remove a credential from the sensitive list (opaquely) */
+    public void removeSensCred(Role role) { sens.remove(role); }
+
+    /** 
+     * Predicate function to test whether the supplied role expression is 
+     * sensitive or not. The obj must be a credential for the test to succeed.
+     *
+     * @param obj a credential instance for the predicate to test
+     * @return success of failure of the predicate
+     */
+    public boolean test(EntityExpression obj) {
+	if(!(obj instanceof Role))return true;
+	Role role = (Role)obj;
+	return (sens.contains(role));
+	/*
+	if(!sens.contains(role)) {
+	    return false;
+	}
+	return true;
+	*/
+    }
+    
+}
Index: fedd/abac-src/rbtm/engine/Simp.java
===================================================================
--- fedd/abac-src/rbtm/engine/Simp.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/Simp.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,19 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+/**
+ * A simple predicate to fail only on role expressions which are roles.
+ */
+public class Simp implements Predicate {
+    
+    /** apply the predicate to determine if a role expression isn't a role */
+    public boolean test(EntityExpression obj) {
+	if(obj instanceof Role) {
+	    return false;
+	}
+	return true;
+    }
+
+}
Index: fedd/abac-src/rbtm/engine/SimpleProofQueue.java
===================================================================
--- fedd/abac-src/rbtm/engine/SimpleProofQueue.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/SimpleProofQueue.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,45 @@
+package edu.stanford.peer.rbtm.engine;
+
+import java.util.*;
+
+/**
+ * SimpleProofQueue maintains two queues of nodes that have not been visited, 
+ * one for forward, and one for backward.
+ */
+public class SimpleProofQueue implements ProofQueue
+{
+	//HashSet 	forwardNodes = new HashSet();
+	//HashSet     backwardNodes = new HashSet();
+	LinkedList  forwardQueue = new LinkedList();
+	LinkedList  backwardQueue = new LinkedList();
+
+    public boolean hasUnexploredForwardNodes() { 
+    	return !forwardQueue.isEmpty(); 
+    }
+
+    public boolean hasUnexploredBackwardNodes() { 
+    	return !backwardQueue.isEmpty(); 
+    }
+
+    public ProofNode nextUnexploredForwardNode() { 
+        return (ProofNode)forwardQueue.removeFirst(); 
+    }
+
+    public ProofNode nextUnexploredBackwardNode() { 
+        return (ProofNode)backwardQueue.removeFirst(); 
+    }
+
+    public void addForwardNode(ProofNode node) {
+		//if (! forwardNodes.contains(node)) {
+			forwardQueue.add(node);
+		//	forwardNodes.add(node);
+		//}
+    }
+
+    public void addBackwardNode(ProofNode node) {
+		//if (! backwardNodes.contains(node)) {
+			backwardQueue.add(node);
+		//	backwardNodes.add(node);
+		//}
+    }
+}
Index: fedd/abac-src/rbtm/engine/SolutionFilter.java
===================================================================
--- fedd/abac-src/rbtm/engine/SolutionFilter.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/SolutionFilter.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,20 @@
+package edu.stanford.peer.rbtm.engine;
+
+import edu.stanford.peer.rbtm.credential.*;
+
+public interface SolutionFilter
+{
+	ForwardSolution getForwardSolution(EntityExpression re);
+	BackwardSolution getBackwardSolution(EntityExpression re);
+}
+
+
+
+
+
+
+
+
+
+
+
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
+
Index: fedd/abac-src/rbtm/engine/package.html
===================================================================
--- fedd/abac-src/rbtm/engine/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/engine/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,3 @@
+<BODY>
+<P> A package containing classes for a credential graph and graph nodes. </P>
+</BODY>
Index: fedd/abac-src/rbtm/test/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/test/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,18 @@
+/EPub.java/1.3/Tue Aug 12 17:56:29 2003//
+/README/1.1/Fri Dec 21 18:46:07 2001//
+/Test.java/1.1/Fri Dec 14 21:11:19 2001//
+/TestEngine.java/1.10/Tue Jul 23 16:50:30 2002//
+/abac.conf/1.4/Mon Jul 29 21:59:35 2002//
+/cred.txt/1.2/Thu Dec 20 20:44:44 2001//
+/frontier-creds.txt/1.1/Fri Dec 21 18:46:07 2001//
+/frontier-desired-oppo-output.txt/1.1/Fri Dec 21 18:46:07 2001//
+/frontier-desired-sens-output.txt/1.1/Fri Dec 21 18:46:07 2001//
+/frontier-desired-simp-output.txt/1.1/Fri Dec 21 18:46:07 2001//
+/frontier-searches.txt/1.1/Fri Dec 21 18:46:07 2001//
+/issuer-tracable.txt/1.1/Fri Dec 21 18:46:07 2001//
+/med-cred.txt/1.1/Thu Dec 20 20:37:11 2001//
+/med.conf/1.2/Wed Feb 13 21:09:05 2002//
+/package.html/1.2/Tue Dec 18 01:38:12 2001//
+/searches.txt/1.1/Thu Dec 20 20:37:11 2001//
+/sensitive.txt/1.1/Fri Dec 21 18:46:07 2001//
+D
Index: fedd/abac-src/rbtm/test/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/test/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/test
Index: fedd/abac-src/rbtm/test/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/test/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/test/EPub.java
===================================================================
--- fedd/abac-src/rbtm/test/EPub.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/EPub.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,83 @@
+package edu.stanford.peer.rbtm.test;
+
+import edu.stanford.peer.rbtm.engine.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+public class EPub 
+{
+    static GraphEngine mgr = new GraphEngine();
+    static Entity alice = new SimpleEntity("Alice");
+    static Entity bob = new SimpleEntity("Bob");
+    static EntityExpression[] parts;
+
+    public static void main(String arg[]) {
+	loadCredentials();
+	performSearches();
+    }
+
+    public static void performSearches() {
+	System.out.println("Credential Manager contains:");
+	System.out.println(mgr);
+	System.out.println("Forward search on " + alice + ":");
+	System.out.println(mgr.forwardSearch(alice));
+	System.out.println("------------------------------------");
+	System.out.println("Backward search on EPub.student:\n");
+	System.out.println(mgr.backwardSearch(new Role("EPub", "student")));
+	System.out.println("Backward search on EOrg.preferred:\n ");
+	System.out.println(mgr.backwardSearch(new Role("EOrg", "preferred")));
+
+	parts = loadRoles();
+	Intersection i = new Intersection();
+	i.and(parts[0]).and(parts[1]);
+	System.out.println("Backward search on " + i + ":\n ");
+	System.out.println(mgr.backwardSearch(i));
+    }
+
+    public static EntityExpression[] loadRoles() {
+	EntityExpression[] parts = new EntityExpression[2];
+	parts[0] = new Role("EPub", "student");
+	parts[1] = new Role("EOrg", "preferred");
+	return parts;
+    }
+    
+    public static void loadCredentials() {
+	SimpleEntity abu  = new SimpleEntity("ABU"),
+	    acm  = new SimpleEntity("ACM"),
+	    bbb  = new SimpleEntity("BBB"),
+	    eOrg = new SimpleEntity("EOrg"),
+ 	    ePub = new SimpleEntity("EPub"),
+	    stateU = new SimpleEntity("StateU");
+	SimpleRoleName stuID = new SimpleRoleName("stuID"),
+	    accredited = new SimpleRoleName("accredited"),
+	    student = new SimpleRoleName("student"),
+	    univ = new SimpleRoleName("university"),
+	    member = new SimpleRoleName("member"),
+	    preferred = new SimpleRoleName("preferred"),
+		 sale = new SimpleRoleName("sale"), 
+	    discount = new SimpleRoleName("spdiscount");
+	Role ePubUniv = new Role(ePub, univ),
+	    acmMember = new Role(acm, member),
+	    abuAccredited = new Role(abu, accredited);
+	LinkedRole ePubUnivStuID = new LinkedRole(ePubUniv, stuID);
+	Intersection u = new Intersection();
+	u.and(new Role(eOrg, preferred)).and(new Role(ePub, student));
+	mgr.addCredential(new StaticCredential(new Role(ePub, sale),
+														new Role(ePub, discount)));
+	mgr.addCredential(new StaticCredential(ePub, discount, u));
+	mgr.addCredential(new StaticCredential(eOrg, preferred, acmMember));
+	mgr.addCredential(new StaticCredential(acmMember, alice));
+	mgr.addCredential(new StaticCredential(acmMember, bob));
+	mgr.addCredential(new StaticCredential(ePub, student, ePubUnivStuID));
+	mgr.addCredential(new StaticCredential(ePubUniv, abuAccredited));
+	mgr.addCredential(new StaticCredential(abuAccredited, stateU));
+	mgr.addCredential(new StaticCredential(stateU, stuID, alice));
+	mgr.addCredential(new StaticCredential(stateU, stuID, bob));
+	//mgr.addCredential(new StaticCredential());
+    }
+
+}
+
+
+
+
Index: fedd/abac-src/rbtm/test/README
===================================================================
--- fedd/abac-src/rbtm/test/README	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/README	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,13 @@
+Input files for testing frontier functions:
+
+frontier-creds.txt -- credentials to use for testing frontier
+frontier-searches.txt -- role expressions from which to perform all three frontier searches
+issuer-tracable.txt -- issuer-tracable role names
+sensitive.txt -- roles Alice considers sensitive
+
+
+Desired output files:
+
+frontier-desired-simp-output.txt 
+frontier-desired-oppo-output.txt
+frontier-desired-sens-output.txt
Index: fedd/abac-src/rbtm/test/Test.java
===================================================================
--- fedd/abac-src/rbtm/test/Test.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/Test.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,189 @@
+package edu.stanford.peer.rbtm;
+
+import java.io.*;
+import java.util.*;
+import edu.stanford.peer.rbtm.engine.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+public class Test 
+{
+    public static void main(String args[]) throws Exception {
+		//test1();
+		test3();
+        //test3(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
+    }
+
+    static void test1() throws Exception {
+        CredentialManager cs = new CredentialManager();
+        cs.addCredential(new StaticCredential("university", "professors", "university.depts.professors"));
+        cs.addCredential(new StaticCredential("dept_cs", "professors", "mitchell"));
+        cs.addCredential(new StaticCredential("university", "depts", "dept_cs"));
+        System.out.println(cs.toString());
+        System.out.println();
+        cs.removeCredential(new StaticCredential("university", "depts", "dept_cs"));
+        System.out.println(cs.toString());
+        System.out.println();
+
+        Role r = new Role("university", "professors");
+        System.out.println(cs.backwardSearch(r));
+        System.out.println(cs.forwardSearch(new SimpleEntity("mitchell")));
+
+    }
+
+    static void test2() throws Exception {
+	    CredentialManager cs = new CredentialManager();
+	    SimpleEntity 	tony = new SimpleEntity("Tony"),
+	    				carmela = new SimpleEntity("Carmela"),
+	    				melfi = new SimpleEntity("Jennifer Melfi"),
+	    				livia = new SimpleEntity("Livia"),
+	    				junior = new SimpleEntity("Junior"),
+	    				chris = new SimpleEntity("Chris Moltisanti"),
+	    				meadow = new SimpleEntity("Meadow"),
+	    				anthony = new SimpleEntity("Anthony Jr."),
+	    				paulie = new SimpleEntity("Paulie Walnuts"),
+	    				jackie = new SimpleEntity("Jackie Aprile");
+
+	    Role 	tonyWifeRole = new Role(tony, "Wife"),
+	    		tonyFamilyRole = new Role(tony, "Family Members"),
+	    		tonyChildrenRole = new Role(tony, "Children"),
+	    		tonyCrewRole = new Role(tony, "Crew"),
+	    		tonyMotherRole = new Role(tony, "Mother"),
+	    		tonyBossRole = new Role(tony, "Boss"),
+	    		tonyUncleRole = new Role(tony, "Uncle"),
+	    		melfiPatientRole = new Role(melfi, "Patients"),
+	    		melfiPreferredPatientRole = new Role(melfi, "Preferred Patients"),
+	    		chrisBossRole = new Role(chris, "Boss"),
+	    		chrisActingBossRole = new Role(chris, "ActingBoss"),
+	    		chrisGangRole = new Role(chris, "Gang");
+	    
+	    ArrayList tonyCreds = new ArrayList(20);
+	    
+	    tonyCreds.add(new StaticCredential(tonyWifeRole, carmela));
+	    tonyCreds.add(new StaticCredential(tonyFamilyRole, tonyWifeRole));
+	    tonyCreds.add(new StaticCredential(tonyFamilyRole, tonyChildrenRole));
+	    tonyCreds.add(new StaticCredential(tonyChildrenRole, meadow));
+	    tonyCreds.add(new StaticCredential(tonyChildrenRole, anthony));
+	    tonyCreds.add(new StaticCredential(tonyCrewRole, chris));
+	    tonyCreds.add(new StaticCredential(tonyCrewRole, paulie));
+	    tonyCreds.add(new StaticCredential(tonyMotherRole, livia));
+	    tonyCreds.add(new StaticCredential(tonyBossRole, jackie));
+	    tonyCreds.add(new StaticCredential(tonyUncleRole, junior));
+	    // Setting up credentials for toni
+	    cs.addCredentials(tonyCreds); 
+
+	    ArrayList melfiCreds = new ArrayList(5);
+	    melfiCreds.add(new StaticCredential(melfiPatientRole, melfiPreferredPatientRole));
+	    melfiCreds.add(new StaticCredential(melfiPreferredPatientRole, tony));
+	    cs.addCredentials(melfiCreds); 
+
+	    
+	    ArrayList chrisCreds = new ArrayList(5);
+	    cs.addCredential(new StaticCredential(chrisBossRole, tony));
+	    cs.addCredential(new StaticCredential(chrisActingBossRole, tonyBossRole));
+	    cs.addCredential(new StaticCredential(chrisGangRole, new LinkedRole(chrisBossRole, "Crew")));
+
+		System.out.println(cs.toString());
+		System.out.println();
+		System.out.println(cs.forwardSearch(carmela));
+		System.out.println();
+
+		cs.removeCredential(new StaticCredential(chrisBossRole, tony));
+		cs.removeCredential(new StaticCredential(chrisActingBossRole, tonyBossRole));
+
+		cs.addCredential(new StaticCredential(chrisGangRole, new Role("Tony", "Wife")));
+		cs.addCredential(new StaticCredential(new Role("Meadow", "Mother"), new Role("Tony", "Wife")));
+
+		System.out.println(cs.toString());
+		System.out.println();
+		System.out.println(cs.forwardSearch(carmela));
+		System.out.println();
+
+		//System.out.println(cs.forwardSearch(jackie));
+		//System.out.println();
+	}
+	
+	
+	static void test3() throws Exception
+	{
+		CredentialManager store = new CredentialManager();
+
+		store.addCredential(new StaticCredential("sbose", "picturesRead", "sbose.family"));
+		store.addCredential(new StaticCredential("sbose", "picturesWrite", "sbose.family"));
+		store.addCredential(new StaticCredential("sbose", "picturesRead", "sbose.family.friends"));
+		store.addCredential(new StaticCredential("sbose", "picturesRead", "patrick"));
+		store.addCredential(new StaticCredential("sbose", "picturesWrite", "andrew"));
+		store.addCredential(new StaticCredential("sbose", "picturesWrite", "patrick"));
+
+		System.out.println(store.toString() + "\n\n");
+
+		ResultEvidenceMap result = store.forwardSearch(new SimpleEntity("andrew"));
+		Set resultSet = result.resultSet();
+		System.out.println("forward andrew is: " + resultSet);
+		Iterator it = resultSet.iterator();
+		while (it.hasNext()) {
+		    System.out.println(it.next().toString());
+		}
+
+		//add a credential
+		store.addCredential(new StaticCredential("sbose", "picturesRead", "andrew"));
+
+		System.out.println("\n\n added credential sbose.picturesRead <- andrew");
+
+		System.out.println("\n" + store.toString() + "\n\n" + "forward search on entity andrew:");
+
+		result = store.forwardSearch(new SimpleEntity("andrew"));
+		resultSet = result.resultSet();
+		System.out.println("forward andrew is: " + resultSet);
+		it = resultSet.iterator();
+		while (it.hasNext()) {
+		    System.out.println(it.next().toString());
+		}
+
+
+		//remove a credential
+		//
+		//
+
+		store.removeCredential(new StaticCredential("sbose", "picturesWrite", "patrick"));
+
+		System.out.println("\n\n removed credential sbose.picturesWrite <- patrick");
+
+		System.out.println("\n" + store.toString() + "\n\n" + "forward search on patrick:");
+
+		result = store.forwardSearch(new SimpleEntity("patrick"));
+		resultSet = result.resultSet();
+		it = resultSet.iterator();
+		while (it.hasNext()) {
+		    System.out.println(it.next().toString());
+		}
+	}
+
+
+
+    static void test4(int l, int n) throws Exception {
+        CredentialManager cs = new CredentialManager();
+        for (int j=0; j<n; j++) {
+            cs.addCredential(new StaticCredential("K", "C", "K.C"+l+".B"+j));
+        }
+            cs.addCredential(new StaticCredential("K", "C1", "K0.A"));
+        for (int i=1; i<l; i++) {
+            int j = i+1;
+            cs.addCredential(new StaticCredential("K", "C"+j, "K.C"+i+".A"));
+        }
+        for (int i=0; i<n; i++) {
+            cs.addCredential(new StaticCredential("K0", "A", "K"+i));
+        }
+        for (int i=0; i<n; i++) {
+            int j = (i+1) % n;
+            cs.addCredential(new StaticCredential("K"+i, "A", "K"+j+".A"));
+        }
+        System.out.println(cs.toString());
+        cs.forwardSearch(new SimpleEntity("K0"));
+
+        cs.backwardSearch(new Role("K", "C"));
+
+        //engine.bidirectionSearch(new Role("K0", "B0"), new Role("K", "C"));
+    }
+
+}
Index: fedd/abac-src/rbtm/test/TestEngine.java
===================================================================
--- fedd/abac-src/rbtm/test/TestEngine.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/TestEngine.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,223 @@
+package edu.stanford.peer.rbtm.test;
+
+import java.io.*;
+import java.util.*;
+
+import edu.stanford.peer.rbtm.RBTMConstants;
+import edu.stanford.peer.rbtm.engine.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.*;
+
+public class TestEngine implements RBTMConstants {
+
+    static HashSet credSet;
+
+    static GraphEngine mgr, oppoEngine, sensEngine, simpEngine;
+
+    static PrintStream out, oppoOut, sensOut, simpOut;
+
+    static String outPrefix = "frontier";
+
+    static void createOutput(String prefix) {
+	if(prefix == null || prefix.length() == 0) 
+	    prefix = outPrefix;
+	try {
+	    out = new PrintStream(new FileOutputStream(prefix + "-cred.txt"));
+	oppoOut = new PrintStream(new FileOutputStream(prefix + "-oppo.txt"));
+	sensOut = new PrintStream(new FileOutputStream(prefix + "-sens.txt"));
+	simpOut = new PrintStream(new FileOutputStream(prefix + "-simp.txt"));
+	}
+	catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+    }
+
+    static void parseSection(BufferedReader in, HashMap conf) 
+	throws Exception {
+	HashSet set = new HashSet();
+	String name = null;
+	try {
+	    String heading = in.readLine();
+	    while(heading.startsWith("#")) {
+		System.out.println("Skipping over: " + heading);
+		heading = in.readLine();
+	    }
+	    StringTokenizer st = new StringTokenizer(heading, "[]");
+	    name = st.nextToken().trim();
+	    System.out.println("Processing section " + name);
+	    conf.put(name, set);
+	    while(true) {
+		String line = in.readLine().trim();
+		if(line.length() < 1)
+		    return;
+		if(!line.startsWith("#")) {
+		    System.out.println("line = '" + line + "'");
+		    set.add(line);
+		}
+	    }
+	}
+	catch(EOFException eof) {
+	    conf.put(name, set);
+	    throw eof;
+	}
+	catch(Exception ex) {
+	    //ex.printStackTrace();
+	    throw(ex);
+	}
+    }
+
+    public static HashMap loadConfiguration(String name) {
+	HashMap confMap = new HashMap(6);
+	try {
+	    BufferedReader in = new BufferedReader(new FileReader(name));
+	    while(true) {
+		parseSection(in, confMap);
+	    }
+	}
+	catch(Exception ex) {
+	    //ex.printStackTrace();
+	    return confMap;
+	}
+    }
+
+
+    static HashSet loadCredentials(HashMap confs) {
+	HashSet credSet = new HashSet();
+
+	try {
+	    Iterator i = ((HashSet)confs.get("credentials")).iterator();
+	    while(i.hasNext()) {
+		credSet.add(new StaticCredential((String)i.next()));
+	    }
+	}
+	catch(Exception ex) {
+	    //ex.printStackTrace();
+	    return credSet;
+	}
+	return credSet;
+    }
+    
+    static HashSet loadTraceable(HashMap conf) {
+	HashSet names = new HashSet();
+
+	try {
+	    Iterator i = ((HashSet)conf.get("traceable")).iterator();
+	    while(i.hasNext()) {
+		names.add(new SimpleRoleName((String)i.next()));
+	    }
+	}
+	catch(Exception ex) {
+	    ex.printStackTrace();
+	    return names;
+	}
+	System.out.println("traceable: " + names);
+	return names;
+    }
+
+    static HashSet loadSensitive(HashMap conf) {
+	HashSet sens = new HashSet();
+
+	try {
+	    Iterator i = ((HashSet)conf.get("sensitive")).iterator();
+	    while(i.hasNext()) {
+		sens.add(StaticCredential.getRole((String)i.next()));
+	    }
+	}
+	catch(Exception ex) {
+	    ex.printStackTrace();
+	    return sens;
+	}
+	System.out.println("sensitive: " + sens);
+	return sens;
+    }
+
+
+    static void createEngines(HashMap conf) {
+	Oppo oppo = new Oppo(new Vector(loadTraceable(conf)));
+	Sens sens = new Sens(new Vector(loadSensitive(conf)));
+	Simp simp = new Simp();
+	int track = TRACK_ALL;
+
+	System.out.println("------> Credential Graph");
+	mgr = new GraphEngine(credSet, track, null, null);
+	System.out.println("------> Opponent Graph");
+	oppoEngine = new GraphEngine(credSet, track, null, oppo);
+	System.out.println("------> Sensitive Graph");
+	sensEngine = new GraphEngine(credSet, track, null, sens);
+	System.out.println("------> Simple Graph");
+	simpEngine = new GraphEngine(credSet, track, null, simp);
+     }
+
+    static void searchExpression
+        (EntityExpression child, GraphEngine graph, PrintStream out) {
+        ResultEvidenceMap map = graph.backwardSearch(child);
+        Iterator i = map.resultSet().iterator();
+        while(i.hasNext()) {
+            EntityExpression ancestor = (EntityExpression)i.next();
+            HashSet chain = graph.getChain(child, ancestor);
+            Iterator credentials = chain.iterator();
+
+            out.println("Credential chain for" + child + "<--" + ancestor );
+            while(credentials.hasNext()) {
+                out.print("\t");
+                out.println(credentials.next());
+            }
+        }
+    }
+
+    static void searchExpression(EntityExpression expr) {
+	System.out.println("[cred for " + expr + "]");
+	out.println("Credential Graph of  " + expr + " = " +
+				   mgr.backwardSearch(expr));
+    searchExpression(expr, mgr, out);
+	System.out.println("[oppo for " + expr + "]");
+	oppoOut.println("Oppo Frontier of  " + expr + " = " +
+				   oppoEngine.backwardSearch(expr));
+	oppoOut.println("[oppo chains for " + expr + "]");
+    searchExpression(expr, oppoEngine, oppoOut);
+	System.out.println("[sens for " + expr + "]");
+	sensOut.println("Sens Frontier of  " + expr + " = " +
+				   sensEngine.backwardSearch(expr));
+	sensOut.println("[sens chains for " + expr + "]");
+    searchExpression(expr, sensEngine, sensOut);
+	System.out.println("[simp for " + expr + "]");
+	simpOut.println("Simp Frontier of  " + expr + " = " +
+				   simpEngine.backwardSearch(expr));
+	simpOut.println("[simp chains for " + expr + "]");
+    searchExpression(expr, sensEngine, sensOut);
+    }
+
+    static void performSearches(HashMap conf) {
+	String line;
+	EntityExpression expr;
+	
+	try {
+	    Iterator i = ((HashSet)conf.get("searches")).iterator();
+	    while(i.hasNext()) {
+		expr = StaticCredential.getEntityExpression
+		    (((String)i.next()).trim());
+		searchExpression(expr);
+	    }
+	}
+	catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+	
+    }
+
+
+
+
+    public static void main(String arg[]) {
+	HashMap conf = loadConfiguration((arg.length > 0)?arg[0]:"abac.conf");
+	credSet = loadCredentials(conf);
+
+	createEngines(conf);
+	createOutput("frontier");
+	performSearches(conf);
+    }
+
+}
+ 
+
+
Index: fedd/abac-src/rbtm/test/abac.conf
===================================================================
--- fedd/abac-src/rbtm/test/abac.conf	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/abac.conf	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,37 @@
+[credentials]
+EPub.discount <- EOrg.preferred ^ EPub.student
+EOrg.preferred <- ACM.member
+EOrg.preferred <- IEEE.member
+ACM.member <- Alice
+ACM.member <- Cindy
+ACM.member <- Brian
+EPub.student <- EPub.university.stuId
+EPub.university <- ABU.accredited
+ABU.accredited <- StateU
+StateU.stuId <- Alice
+StateU.stuId <- Cindy
+
+[sensitive]
+IEEE.member
+StateU.stuId
+
+[traceable]
+spdiscount
+preferred
+student
+university
+
+[searches]
+EPub.discount 
+EOrg.preferred ^ EPub.student
+EOrg.preferred 
+IEEE.member
+ACM.member 
+EPub.student 
+EPub.university.stuId
+EPub.university 
+ABU.accredited
+StateU
+StateU.stuId 
+Alice
+Brian
Index: fedd/abac-src/rbtm/test/cred.txt
===================================================================
--- fedd/abac-src/rbtm/test/cred.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/cred.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,9 @@
+EOrg.preferred<-ACM.Member
+ACM.Member<-Alice
+ACM.Member<-Cindy
+ACM.Member<-Brian
+EPub.student<-EPub.University.StuId
+EPub.University<-ABU.Accredited
+ABU.Accredited<-StateU
+StateU.StuId<-Alice
+StateU.StuId <- Cindy
Index: fedd/abac-src/rbtm/test/frontier-creds.txt
===================================================================
--- fedd/abac-src/rbtm/test/frontier-creds.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/frontier-creds.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,11 @@
+EPub.discount <- EOrg.preferred ^ EPub.student
+EOrg.preferred <- ACM.member
+EOrg.preferred <- IEEE.member
+ACM.member <- Alice
+ACM.member <- Cindy
+ACM.member <- Brian
+EPub.student <- EPub.university.stuId
+EPub.university <- ABU.accredited
+ABU.accredited <- StateU
+StateU.stuId <- Alice
+StateU.stuId <- Cindy
Index: fedd/abac-src/rbtm/test/frontier-desired-oppo-output.txt
===================================================================
--- fedd/abac-src/rbtm/test/frontier-desired-oppo-output.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/frontier-desired-oppo-output.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,15 @@
+				
+EPub.discount				{ EOrg.preferred ^ EPub.student }
+EOrg.preferred ^ EPub.student		{ EOrg.preferred ^ EPub.student }
+EOrg.preferred			      *	{ IEEE.member, ACM.member }  
+IEEE.member			      *	{ IEEE.member }
+ACM.member				{ ACM.member }
+EPub.student				{ EPub.university.stuId }
+EPub.university.stuId			{ EPub.university.stuId }
+EPub.university			      *	{ ABU.accredited }
+ABU.accredited			      *	{ ABU.accredited }
+StateU					{ StateU }
+StateU.stuId			      *	{ StateU.stuId }
+Alice					{ Alice }
+Brian					{ Brian }
+Cindy					{ Cindy }
Index: fedd/abac-src/rbtm/test/frontier-desired-sens-output.txt
===================================================================
--- fedd/abac-src/rbtm/test/frontier-desired-sens-output.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/frontier-desired-sens-output.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,15 @@
+				
+EPub.discount				{ EOrg.preferred ^ EPub.student }
+EOrg.preferred ^ EPub.student		{ EOrg.preferred ^ EPub.student }
+EOrg.preferred			      *	{ Alice, Cindy, Brian, IEEE.member }
+IEEE.member			      *	{ IEEE.member }
+ACM.member				{ Alice, Cindy, Brian }
+EPub.student				{ EPub.university.stuId }
+EPub.university.stuId			{ EPub.university.stuId }
+EPub.university				{ StateU }
+ABU.accredited				{ StateU }
+StateU					{ StateU }
+StateU.stuId			      *	{ StateU.stuId }
+Alice					{ Alice }
+Brian					{ Brian }
+Cindy					{ Cindy }
Index: fedd/abac-src/rbtm/test/frontier-desired-simp-output.txt
===================================================================
--- fedd/abac-src/rbtm/test/frontier-desired-simp-output.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/frontier-desired-simp-output.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,15 @@
+				
+EPub.discount				{ EOrg.preferred ^ EPub.student }
+EOrg.preferred ^ EPub.student		{ EOrg.preferred ^ EPub.student }
+EOrg.preferred				{ Alice, Cindy, Brian }
+IEEE.member				{ }
+ACM.member				{ Alice, Cindy, Brian }
+EPub.student				{ EPub.university.stuId }
+EPub.university.stuId			{ EPub.university.stuId }
+EPub.university				{ StateU }
+ABU.accredited				{ StateU }
+StateU					{ StateU }
+StateU.stuId				{ Alice, Brian }
+Alice					{ Alice }
+Brian					{ Brian }
+Cindy					{ Cindy }
Index: fedd/abac-src/rbtm/test/frontier-searches.txt
===================================================================
--- fedd/abac-src/rbtm/test/frontier-searches.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/frontier-searches.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,13 @@
+EPub.discount 
+EOrg.preferred ^ EPub.student
+EOrg.preferred 
+IEEE.member
+ACM.member 
+EPub.student 
+EPub.university.stuId
+EPub.university 
+ABU.accredited
+StateU
+StateU.stuId 
+Alice
+Brian
Index: fedd/abac-src/rbtm/test/issuer-tracable.txt
===================================================================
--- fedd/abac-src/rbtm/test/issuer-tracable.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/issuer-tracable.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,4 @@
+spdiscount
+preferred
+student
+university
Index: fedd/abac-src/rbtm/test/med-cred.txt
===================================================================
--- fedd/abac-src/rbtm/test/med-cred.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/med-cred.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,2 @@
+MedixFund.pA <-- Alice
+ReliefNet.coaMember <-- MedixFund
Index: fedd/abac-src/rbtm/test/med.conf
===================================================================
--- fedd/abac-src/rbtm/test/med.conf	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/med.conf	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,18 @@
+[credentials]
+MedixFund.purchasingA <-- Alice
+ReliefNet.member <-- MedixFund
+MedSup.cPartner <-- ReliefNet.member
+MedSup.discount <-- MedSup.cPartner.purchasingA
+
+[sensitive]
+MedixFund.purchasingA
+
+[traceable]
+discount
+member
+purchasingA
+
+[searches]
+MedSup.cPartner
+Alice
+MedSup.discount
Index: fedd/abac-src/rbtm/test/package.html
===================================================================
--- fedd/abac-src/rbtm/test/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,4 @@
+<BODY>
+   <P>Testing frameworks to gauge the RBTM and ABAC packages. The class is for 
+      the rbtm packages. EPub and Engine are newer testing applications.</P>
+</BODY>
Index: fedd/abac-src/rbtm/test/searches.txt
===================================================================
--- fedd/abac-src/rbtm/test/searches.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/searches.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,4 @@
+EOrg.preferred
+EPub.University
+EPub.student
+EOrg.preferred ^ EPub.student
Index: fedd/abac-src/rbtm/test/sensitive.txt
===================================================================
--- fedd/abac-src/rbtm/test/sensitive.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/test/sensitive.txt	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,2 @@
+IEEE.member
+StateU.StuId
Index: fedd/abac-src/rbtm/util/CVS/Entries
===================================================================
--- fedd/abac-src/rbtm/util/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/CVS/Entries	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,6 @@
+/Debug.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/Predicate.java/1.1/Wed Dec 19 23:58:54 2001//
+/ResultEvidenceMap.java/1.4/Fri May 17 16:17:54 2002//
+/SmallSet.java/1.1.1.1/Tue Nov 13 17:28:45 2001//
+/package.html/1.2/Tue Dec 18 01:38:12 2001//
+D
Index: fedd/abac-src/rbtm/util/CVS/Repository
===================================================================
--- fedd/abac-src/rbtm/util/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/CVS/Repository	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+rbtm/util
Index: fedd/abac-src/rbtm/util/CVS/Root
===================================================================
--- fedd/abac-src/rbtm/util/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/CVS/Root	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,1 @@
+:ext:jjacobs@src.columbia.sparta.com/cvs/abac
Index: fedd/abac-src/rbtm/util/Debug.java
===================================================================
--- fedd/abac-src/rbtm/util/Debug.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/Debug.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,16 @@
+package edu.stanford.peer.rbtm.util;
+
+import java.io.*;
+
+public class Debug
+{
+	static PrintStream out = System.out;
+
+	static public void debugInfo(String s) {
+		out.println(s);
+	}
+
+	static public void setOutputStream(PrintStream out) {
+		Debug.out = out;
+	}
+}
Index: fedd/abac-src/rbtm/util/Predicate.java
===================================================================
--- fedd/abac-src/rbtm/util/Predicate.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/Predicate.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,24 @@
+package edu.stanford.peer.rbtm.util;
+
+
+import edu.stanford.peer.rbtm.credential.EntityExpression;
+
+/**
+ * A predicate function which tests an object and returns the results. The
+ * class also provides an object reference which may be null.
+ */
+public interface Predicate extends java.io.Serializable 
+{
+    public static final String SIMP = "simple";
+
+    public static final String SENS = "sensitive";
+
+    public static final String OPPO = "opponent";
+
+    /** 
+     * The testing function for a predicate.
+     * @return the success or failure of the predicate 
+     */
+    public boolean test(EntityExpression expr);
+
+}
Index: fedd/abac-src/rbtm/util/ResultEvidenceMap.java
===================================================================
--- fedd/abac-src/rbtm/util/ResultEvidenceMap.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/ResultEvidenceMap.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,81 @@
+package edu.stanford.peer.rbtm.util;
+
+import java.util.*;
+
+import edu.stanford.peer.rbtm.RBTMConstants;
+//import edu.stanford.peer.rbtm.util.*;
+
+/** Stores results and their evidences. */
+public class ResultEvidenceMap implements RBTMConstants
+{
+	static final public int DEFAULT_CAPACITY = 23;
+
+    //private int  	_type = TRACK_NONE;
+    private int  	_type = TRACK_ALL;
+    private HashMap _map;
+
+    public ResultEvidenceMap(int trackType, int capacity) {
+    	_type = trackType; 
+    	_map = new HashMap(capacity);
+    }
+
+    public ResultEvidenceMap() { 
+		this(TRACK_ALL, DEFAULT_CAPACITY);
+    }
+
+    public ResultEvidenceMap(int trackType) { 
+	    this(trackType, DEFAULT_CAPACITY);
+	}
+
+    /**
+     * Retrieve a Result-to-Evidence mapping. If constructed with trackType
+     * TRACK_NONE, the evidence will be null.
+     * @return the evidence, if any, bound to the result.
+     */
+    public Object getResultEvidence(Object result) {
+	return _map.get(result);
+    }
+
+	/**
+	 * Add a Result-to-Evidence mapping.  
+	 * @return true if this is a new Result, false if it is not
+	 */
+    public boolean putResultEvidence(Object result, Object evidence) {
+        if (! _map.containsKey(result)) {  // New result
+			switch (_type) {
+			case TRACK_NONE:
+	            _map.put(result, null);
+				break;
+			case TRACK_ANY:
+				_map.put(result, evidence);
+				break;
+			case TRACK_ALL:
+				HashSet eviSet = new HashSet(7);
+				eviSet.add(evidence);
+				System.out.println("###Adding " + result + ","
+						   + evidence);
+				_map.put(result, eviSet);
+				break;
+			}
+            return true;
+        } else {  // Result already exist
+            if (_type == TRACK_ALL) {
+                ((Set)_map.get(result)).add(evidence);
+            }
+            return false;
+        }
+    }
+    
+    public boolean containsResult(Object result) {
+        return _map.containsKey(result);
+    }
+
+	public Set resultSet() {
+		return _map.keySet();
+	}
+
+	public String toString() {
+	    return  "["+ _type + "]" + _map.toString();
+	    //return _map.toString();
+	}
+}
Index: fedd/abac-src/rbtm/util/SmallSet.java
===================================================================
--- fedd/abac-src/rbtm/util/SmallSet.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/SmallSet.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,17 @@
+package edu.stanford.peer.rbtm.util;
+
+import java.util.*;
+
+/** A set that typically contains just one member, but may contain
+    more than one.  Using SmallSet instead of HashSet could avoid 
+	the cost of creating lots of HashSet when it is not necessary.
+	The current implementation simply extends HashSet.
+ */
+public class SmallSet extends HashSet
+{
+	Object o;
+    public SmallSet(Object o) {
+        super();
+        add(o);
+    }
+}
Index: fedd/abac-src/rbtm/util/package.html
===================================================================
--- fedd/abac-src/rbtm/util/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/rbtm/util/package.html	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,5 @@
+<BODY>
+<P>
+Utility classes which are intended for generic use in other packages.
+</P>
+</BODY>
