Index: fedd/abac-src/ttg/test/PropertiesObserver.java
===================================================================
--- fedd/abac-src/ttg/test/PropertiesObserver.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/test/PropertiesObserver.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,253 @@
+package com.nailabs.abac.test;
+
+import java.util.*;
+import java.io.*;
+
+
+import com.nailabs.abac.trust.*;
+import com.nailabs.abac.process.*;
+import edu.stanford.peer.rbtm.credential.*;
+
+public class PropertiesObserver implements Observer {
+    PrintStream out;
+    int major = 0, minor = 0;
+    int policy = 1;
+    HashMap nodeMap = new HashMap(10);
+    Entity me;
+    boolean myLocal = false;
+    boolean mySync = false;
+    Vector aSync = new Vector();
+
+    public PropertiesObserver(Entity eid) {
+        String name = eid.toString();
+        FrontierManager mgr = FrontierManager.getFrontier(eid);
+        me = eid;
+        try {
+            String logName = name + ".log";
+            File propFile = new File(name + ".prop");
+            File logFile = new File(name + ".log");
+            if(propFile.exists()){
+                propFile.renameTo(logFile);
+            }
+            out = new PrintStream(new FileOutputStream(name + ".prop"));
+        }
+        catch(Exception ex) {
+            ex.printStackTrace(out);
+        }
+        out.println("subject = " + name);
+        printACPolicy(mgr.getACPolicy());
+        printAckPolicy(mgr.getAckPolicy());
+        out.println();
+    }
+
+    private void printACPolicy(ACPolicy policy) {
+        final String AC = "AC";
+        if(policy == null)return;
+        Vector keys = policy.getProtectedCredentials();
+        if(keys == null)return;
+        for(int i = 0; i < keys.size(); i++) {
+            Credential cred = (Credential)keys.elementAt(i);
+            EntityExpression expr = policy.requires(cred);
+            printPolicy(AC, cred.toString(), (expr == null)? "true":
+                        expr.toString());
+        }
+    }
+
+    private void printAckPolicy(AckPolicy policy) {
+        final String ACK = "Ack";
+        if(policy == null)return;
+        Vector keys = policy.getSensitiveRoles();
+        if(keys == null)return;
+        for(int i = 0; i < keys.size(); i++) {
+            EntityExpression sensitive = (EntityExpression)keys.elementAt(i);
+            printPolicy(ACK, sensitive.toString(), 
+                        policy.requires(sensitive).toString());
+        }
+    }
+
+    protected void printPolicy(String type, String key, String value) {
+        StringBuffer buff = new StringBuffer("policy.");
+        buff.append(policy++).append(" = ");
+        buff.append(type).append("[");
+        buff.append(key).append("] = ").append(value);
+        out.println(buff.toString());
+    }
+
+    private void printLocation(String msg) {
+        if(msg.endsWith("init") || myLocal) {
+            myLocal = false;
+            return;
+        }
+        if(msg.endsWith("sync")) {
+            mySync = (msg.endsWith("async"));
+            //printValue("async", mySync + "");
+            //out.println();
+            return;
+        }
+        StringBuffer buff = new StringBuffer("update.");
+        buff.append(++major).append(".");
+        buff.append(msg);
+        out.println(buff.toString());
+        out.println("");
+        minor = 1;
+        for(int offset = 0, max = aSync.size(); offset < max; offset++) {
+            //printValue("offset", offset + "/" + aSync.size());
+            mySync = false;     // it should already be set to false (sanity)
+            printObject(aSync.elementAt(offset));
+        }
+        aSync.clear();
+    }
+    
+    private void printMessage(String msg) {
+        StringBuffer buff = new StringBuffer("update.");
+        buff.append(major).append(".");
+        buff.append(minor).append(".");
+        buff.append(msg);
+        out.println(buff.toString());
+    }
+
+    private void printValue(String label, String value) {
+        StringBuffer buff = new StringBuffer(label);
+        buff.append(" = ").append(value);
+        printMessage(buff.toString());
+    }
+
+    protected void printEdge(EdgeOperation edge) {
+        //if(edge.getType().startsWith("LinkingImplication")) {
+        //}
+        _printEdge(edge);
+    }
+    protected void _printEdge(EdgeOperation edge) {
+        printValue("type", "edge");
+        printValue("edgeType", edge.getType());
+        printValue("parentName", edge.getParent().toString());
+        printValue("childName", edge.getChild().toString());
+        printValue("childType", edge.getChild().getType());
+        printValue("childProcessing", edge.getProcessingState() + "");
+        HashSet evidence = edge.getEvidence();
+        //print out the credentials
+        if(evidence != null) {
+            Iterator i = evidence.iterator();
+            final String EVIDENCE = "evidence.";
+            for(int n = 1; i.hasNext(); n++) {
+                StringBuffer key = new StringBuffer(EVIDENCE); 
+                key.append(n);
+                printValue(key.toString(), i.next().toString());
+            }
+        }
+        out.println();
+    }
+
+    protected void printNode(NodeOperation op) {
+        Goal g = op.getGoal();
+        if(op.isRoot()) {
+            if(g.getVerifier().equals(me)) {
+                printLocation("location = local");
+                myLocal = true;
+            }
+            printValue("type", "node");
+            printValue("name", g.toString());
+            printValue("nodeType", g.getType());
+            printValue("isRoot", "True");
+        } else {
+            printValue("type", "node");
+            printValue("name", g.toString());
+            printValue("processing", op.getProcessingState().toString());
+        }
+        out.println();
+    }
+
+    protected void printNode(TTGNode node) {
+        printValue("type", "node");
+        printValue("nodeType", node.getGoal().getType());
+        printValue("name", node.getGoal().toString());
+        printValue("processing", node.getProcessingState().toString());
+        if(node instanceof TargetNode) {
+            TargetNode tn = (TargetNode)node;
+            int value = tn.getSatisfactionValue();
+            switch(value) {
+            case SatisfactionState.SATISFIED: 
+                printValue("satisfied", "Satisfied");
+                break;
+            case SatisfactionState.FAILED:
+                printValue("satisfied", "Failed");
+                break;
+            default:
+                printValue("satisfied", "Unknown");
+            }
+        } 
+        if(node instanceof LinkingGoalNode) {
+            LinkingGoalNode lgn = (LinkingGoalNode)node;
+            if(lgn.isComplete()) {
+                printValue("satisfied", "Complete");
+            } else {
+                printValue("satisfied", "Incomplete");
+            }
+        }
+        out.println();
+    }
+
+    protected void printObject(Object obj) {
+        if(mySync) {
+            aSync.add(obj);
+            //minor--;
+            return;
+        }
+        if(obj instanceof EdgeOperation) {
+            printEdge((EdgeOperation)obj);
+        }
+        else if(obj instanceof NodeOperation) {
+            printNode((NodeOperation)obj);
+        }
+        else if(obj instanceof TTGNode) {
+            printNode((TTGNode)obj);
+        }
+        else {
+            minor--;
+            //printValue("object", obj.toString());
+        }
+        //out.println();
+        minor++;
+    }
+
+
+    public void update(TTGNode node) {
+        if(!nodeMap.containsKey(node.getGoal().toString())) {
+            nodeMap.put(node.getGoal().toString(), node);
+            node.addObserver(this);
+        }
+    }
+
+
+    public void update(Observable o, Object arg) {
+        if(o instanceof TTG || o instanceof Strategy) {
+            if(arg instanceof TTGNode) {
+                update((TTGNode)arg);
+            }
+            if(arg instanceof String) {
+                String property = (String)arg;
+                if(property.startsWith("location")) {
+                    printLocation(property);
+                    return;
+                } else {
+                    printMessage(property);
+                }
+            }
+            printObject(arg);
+        }
+        printObject(o);
+        
+        //printValue("printing", "arg");
+        //printObject(arg);
+        //out.println();
+    }
+    
+    public void close() {
+        out.flush();
+        out.close();
+    }
+    
+}
+
+
+
