Index: java/Regression.java
===================================================================
--- java/Regression.java	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
+++ java/Regression.java	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
@@ -0,0 +1,59 @@
+import java.io.*;
+import java.util.*;
+
+import net.deterlab.abac.*;
+import net.deterlab.abac.regression.*;
+
+
+/**
+ * Simple test of the native Java implementation of ABAC. Loads credentials
+ * from an rt0 file and runs a query against them.
+ */
+public class Regression {
+
+    static RegressionTest[] tests = new RegressionTest[] {
+	new GENIWriteCreds(),
+    };
+
+    public static void fatal(String s) {
+	if (s != null ) 
+	    System.err.println(s);
+	System.exit(20);
+    }
+
+    public static boolean clearDir(File d) {
+	for (String fn: d.list() ) {
+	    File f = new File(d, fn);
+
+	    if ( f.isDirectory() ) 
+		if ( !clearDir(f) ) return false;
+	    if ( !f.delete() ) return false;
+	}
+	return true;
+    }
+
+
+    public static void main(String[] args) throws IOException {
+	if (args.length < 2 ) 
+	    fatal("Usage Regression regression_data_dir scratch");
+
+	File data = new File(args[0]);
+	File scratch = new File(args[1]);
+
+	if ( !data.isDirectory() ) 
+	    fatal(data + " is not a directory");
+	if ( !scratch.isDirectory() ) 
+	    fatal(scratch + " is not a directory");
+
+	for (RegressionTest test: tests) {
+	    if (!clearDir(scratch) ) 
+		fatal("Could not clear " + scratch);
+
+	    if ( test.runTest(data, scratch)) 
+		System.out.println(test.getName() + " Passed.");
+	    else 
+		fatal(test.getName() + " Failed: " + test.getReason());
+	}
+	System.exit(0);
+    }
+}
Index: java/build.xml
===================================================================
--- java/build.xml	(revision 0100d7ba8efa54a483b670ccd43259a6dec6151b)
+++ java/build.xml	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
@@ -30,4 +30,5 @@
   <property name="read.class" value="Reader"/>
   <property name="write.class" value="Writer"/>
+  <property name="regression.class" value="Regression"/>
   <property name="example.class" value="CreateExample"/>
   <property name="version" value="1.4"/>
@@ -57,5 +58,5 @@
     <mkdir dir="${jar.dir}"/>
     <jar destfile="${jar.dir}/jabac-${version}.jar" basedir="${classes.dir}"
-      excludes="**/GraphTest.class **/Dumper.class">
+      excludes="**/GraphTest.class **/Dumper.class net/deterlab/abac/regression/*">
       <manifest>
 	<attribute name="Class-Path" value="${classpath}" />
@@ -182,3 +183,21 @@
 
   <target name="run-create" depends="run-create-default,run-create-x509,run-create-geni" description="Create all the examples"/>
+
+  <target name="create-scratch" depends="compile" description="Create scratch directory">
+    <delete dir="${src.dir}/scratch"/>
+    <mkdir dir="${src.dir}/scratch"/>
+  </target>
+
+  <target name="run-regression" depends="compile" description="Run the regression test program">
+    <java classname="${regression.class}" fork="true" >
+      <classpath>
+	<path refid="compile.classpath"/>
+	<pathelement path="${classes.dir}"/>
+      </classpath>
+      <arg file="${src.dir}/regression"/>
+      <arg file="${src.dir}/scratch"/>
+    </java>
+  </target>
+
+  <target name="regression-test" depends="create-scratch,run-regression" description="Run the regression test "/>
 </project>
Index: java/net/deterlab/abac/regression/GENIWriteCreds.java
===================================================================
--- java/net/deterlab/abac/regression/GENIWriteCreds.java	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
+++ java/net/deterlab/abac/regression/GENIWriteCreds.java	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
@@ -0,0 +1,120 @@
+package net.deterlab.abac.regression;
+
+import java.io.*;
+import java.util.*;
+
+import net.deterlab.abac.*;
+
+public class GENIWriteCreds extends RegressionTest {
+    /**
+     * Put out an identity and key into dir named by the name of the Identity
+     * @param i the Identity to write
+     * @param dir a File holding the destination directory
+     * @throws IOException if the file writing fails
+     */
+    public void writeCombinedIdentity(Identity i, File dir) 
+	    throws IOException {
+	FileOutputStream f = new FileOutputStream(
+		new File(dir,  i.getName() + ".pem"));
+
+	i.write(f);
+	i.writePrivateKey(f);
+    }
+    /**
+     * Create a new GENI simple proof test
+     */
+     public GENIWriteCreds() { super("GENI credential writing test"); }
+
+    /**
+     * Carry out the test.  Create credentials for the create_experiment
+     * example, run the proof and make sure the correct proof is generated.
+     * @param data a File pointing to a directory that contains files the test
+     * may need
+     * @param scratch a File pointing to a directory that the test can use to
+     * store data
+     * @return a boolean, true if the test is passed
+     */
+    public boolean runTest(File data, File scratch) {
+	try {
+	    Context ctxt = new Context();
+	    Identity acme = new Identity("Acme");
+	    Identity globotron = new Identity("Globotron");
+	    Identity alice = new Identity("Alice");
+	    Identity bob = new Identity("Bob");
+	    Vector<Identity> ids = new Vector<Identity>();
+	    Vector<Credential> creds = new Vector<Credential>();
+	    Collections.addAll(ids, acme, globotron, alice, bob);
+
+	    for ( Identity i: ids) 
+		writeCombinedIdentity(i, scratch);
+
+	    ctxt.setCredentialFactory(new CredentialFactory(
+			new String[] {"net.deterlab.abac.GENICredential"}));
+
+
+	    Credential c = ctxt.newCredential(
+		    new Role(acme.getKeyID() + ".experiment_create"),
+		    new Role(acme.getKeyID() + ".partner.experiment_create"));
+	    c.make_cert(acme);
+	    creds.add(c);
+	    c = ctxt.newCredential(
+		    new Role(acme.getKeyID() + ".partner"),
+		    new Role(globotron.getKeyID()));
+	    c.make_cert(acme);
+	    creds.add(c);
+	    c = ctxt.newCredential(
+		    new Role(globotron.getKeyID() + ".experiment_create"),
+		    new Role(globotron.getKeyID() + ".admin.power_user"));
+	    c.make_cert(globotron);
+	    creds.add(c);
+	    c = ctxt.newCredential(
+		    new Role(globotron.getKeyID() + ".admin"),
+		    new Role(alice.getKeyID()));
+	    c.make_cert(globotron);
+	    creds.add(c);
+	    c = ctxt.newCredential(
+		    new Role(alice.getKeyID() + ".power_user"),
+		    new Role(bob.getKeyID()));
+	    c.make_cert(alice);
+	    creds.add(c);
+
+	    int i =0;
+	    for (Credential cc: creds) {
+		cc.write(new File(scratch, "e" + i + ".cred").toString());
+		i ++;
+	    }
+
+	    Context ctxt2 = new Context();
+
+	    ctxt2.load_directory(scratch);
+	    Collection<Identity> nids = ctxt2.identities();
+	    Collection<Credential> ncreds = ctxt2.credentials();
+
+	    if ( nids.size() != ids.size()) {
+		setReason("Different number of identities read");
+		return false;
+	    }
+	    for (Identity ii: ids ) 
+		if ( !nids.contains(ii)) {
+		    setReason("Identity " + ii + " not read successfully");
+		    return false;
+		}
+
+	    if ( ncreds.size() != creds.size()) {
+		setReason("Different number of credentials read");
+		return false;
+	    }
+	    for (Credential cc: creds ) 
+		if ( !ncreds.contains(cc)) {
+		    setReason("Credential " + cc + " not read successfully");
+		    return false;
+		} 
+
+	}
+	catch (Exception e) {
+	    setReason(e.getMessage());
+	    return false;
+	}
+	return true;
+    }
+}
Index: java/net/deterlab/abac/regression/RegressionTest.java
===================================================================
--- java/net/deterlab/abac/regression/RegressionTest.java	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
+++ java/net/deterlab/abac/regression/RegressionTest.java	(revision 8375d4fe64dd922466b0c5fcea680243b998ce1d)
@@ -0,0 +1,47 @@
+package net.deterlab.abac.regression;
+
+import java.io.*;
+
+public abstract class RegressionTest {
+    /** The name of the test */
+    protected String testName;
+    /** A reason if the test fails */
+    protected String reason;
+
+    /**
+     * Create a new test with the give name.
+     * @param name a String, the test name
+     */
+    protected RegressionTest(String name) {
+	testName = name;
+	reason = null;
+    }
+
+    /**
+     * Return the test name
+     * @return a String the test name
+     */
+    public String getName() { return testName; }
+
+    /**
+     * Return the failure reason (if any)
+     * @return a String the failure reason (if any)
+     */
+    public String getReason() { return reason; }
+
+    /**
+     * Set the failure reason 
+     * @param msg a String holding the new reason
+     */
+    public void setReason(String msg) { reason = msg; }
+
+    /**
+     * Carry out the test
+     * @param data a File pointing to a directory that contains files the test
+     * may need
+     * @param scratch a File pointing to a directory that the test can use to
+     * store data
+     * @return a boolean, true if the test is passed
+     */
+    public abstract boolean runTest(File data, File scratch);
+}
