Index: axis/Create.java
===================================================================
--- axis/Create.java	(revision 9f8dbc1776d1817ba1c1d00011f4f36f1f4a1e36)
+++ axis/Create.java	(revision 709306c47a20c1cc91acbe74a4f7b5051ea8035e)
@@ -1,20 +1,27 @@
+// Java I/O
+import java.io.*;
+
+// The WSDL generated types for messages and components of messages.
 import edu.isi.www.fedd_types.*;
 import edu.isi.www.fedd_wsdl.*;
-import java.net.URL;
-import net.deterlab.isi.XTrustProvider;
-import java.io.*;
-import java.util.*;
 
+// The fault thrown by failed commands
 import org.apache.axis.AxisFault;
 
-import javax.net.*;
-import javax.net.ssl.*;
+// The ABAC commands throw this
 import java.security.GeneralSecurityException;
 
+// ABAC classes.  http://abac.deterlab.net
 import net.deterlab.abac.*;
 
 class Create extends FeddCommand {
 
+    /**
+     * Read a file into a byte array; used to load the topology file.
+     * @param f the File to read
+     * @throws IOException if there is an error reading the file.
+     */
     static public byte[] readNsFile(File f) throws IOException {
+	// This is tedious but straightforward
 	final int bsize = 4096;
 	byte[] buf = new byte[bsize];
@@ -33,4 +40,12 @@
     }
 
+    /**
+     * Create an ABAC credential indicating the the given destination acts for
+     * the given Identity, and attach a certificate to it.
+     * @param id the Identity delegating authority
+     * @param dest the destination
+     * @throws IOException an I/O problem, very unlikely
+     * @throws GeneralSecurityException crypto or identity misconfiguration.
+     */
     static public Credential delegate(Identity id, String dest) 
 	    throws IOException,GeneralSecurityException {
@@ -42,92 +57,111 @@
 
     /**
-     * Dummy program to test an AXIS fedd implementation generated from the
-     * WSDL and run by axis.
-     * It just calls terminate with a dummy id as a local name (which can be
-     * supplied on the command line and reprints the localname that the server
-     * replies with.  A client certificate muct exist in the local keystore
-     * file with the given password. 
+     * Create an experiment with the given mnemonic name, from the given tcl
+     * topology file using the given identity certificate, on the given fedd.
+     * Reads the identity and topology into memory and constructs a New request
+     * for an empty experiment and a Create request to actually start it.  The
+     * start is asynchronous, so this returns when the creation begins, not
+     * when it completes.  
      */
     public static void main(String args[]) throws 
 	    javax.xml.rpc.ServiceException, java.net.MalformedURLException,
 	    java.rmi.RemoteException {
+
+	// Parse out the args
+	String exptName = "test";
+	String tclFile = "./deter-only.tcl";
+	String certFile = "./emulab.pem";
+	String urlString = "https://users.isi.deterlab.net:23235";
+
+	if (args.length > 0) exptName = args[0];
+	if (args.length > 1) tclFile = args[1];
+	if (args.length > 2) certFile = args[2];
+	if (args.length > 3) urlString = args[3];
 	
 	/* 
-	 * Boilerplate web services access stuff.
+	 * Get the Web Service for users and read the identity and topology
 	 */
-	FeddPortType port = getPort("https://users.isi.deterlab.net:23235");
+	FeddPortType port = getPort(urlString);
 	Identity AbacID = null;
 	byte[] nsContents = null;
 	try {
 	    nsContents = readNsFile(new File(args[1]));
+	    AbacID = new Identity(new File("./emulab.pem"));
+	}
+	catch (GeneralSecurityException e) { 
+	    System.err.println("Error reading ABAC identity " + e);
+	    System.exit(20);
 	}
 	catch (IOException e) {
-	    System.err.println("Cannot read " + args[1] + ": " + e);
+	    System.err.println("Cannot load file " + e);
 	    System.exit(20);
 	}
 
 	/*
-	 * The various parts of the MultiInfo message and response
+	 * Build and send a NewRequestType Message
 	 */
 
 	NewRequestType newReq = new NewRequestType(null, 
-		new IDType(null, null, null, args[0], null), 
+		new IDType(null, null, null, exptName, null), 
 		null);
 	NewResponseType newResp = null;
-
-
 	try {
-	    // Build the message and make the call
 	    newResp = port._new(newReq);
 	}
-	catch (Exception f) {
+	catch (AxisFault f) {
 	    System.err.println("Error in New: " + f);
 	    System.exit(20);
 	}
+
+	// Parse out the name of the new empty experiment, and start building
+	// the CreateRequestType message.
 	ExperimentLabels newLabels = 
 	    new ExperimentLabels(newResp.getExperimentID());
-	System.out.println("New success: " + newLabels.getLocalname() + "(" +
-	    newLabels.getFedid() + ")");
 
 	CreateRequestType createReq = new CreateRequestType(null, 
 		new ExperimentDescriptionType(nsContents, null),
 		null,
-		//new IDType(null, null, null, newLabels.getLocalname(), null),
-		new IDType(null, null, null, args[0], null),
+		new IDType(null, null, null, newLabels.getLocalname(), null),
 		null);
 	CreateResponseType createResp = null;
+
+	// Reloading the port clears cached SSL connections.
 	port = getPort("https://users.isi.deterlab.net:23235");
 
-	Credential c = null;
-	byte[][] ca = new byte[1][];
+	// This block creates an ABAC credential telling the fedd that the
+	// experiment we brought to life with the New call above can act with
+	// our authority.  We could keep the certificate around for other
+	// commands to use, but once we tell fedd about it, fedd remembers it.
 	try {
-	    AbacID = new Identity(new File("./emulab.pem"));
+	    Credential c = null;
+	    byte[][] ca = new byte[1][];
+
 	    c = delegate(AbacID, newLabels.getFedid());
 	    ca[0] = c.cert().getEncoded();
 	    createReq.setCredential(ca);
-	    System.err.println(AbacID);
-	    System.err.println(c);
 	}
-	catch (GeneralSecurityException e) { System.err.println(e); }
-	catch (IOException e) { System.err.println("IOException?!!" +e); }
+	catch (GeneralSecurityException e) {
+	    System.err.println("Failed to delegate authority: " + e); 
+	    System.exit(20);
+	}
+	catch (IOException e) { 
+	    System.err.println("Failed to delegate authority: ?!!" +e);
+	    System.exit(20);
+	}
 
+	// The create call
 	try {
-	    /* Build the message and make the call */
 	    createResp = port.create(createReq);
 	}
 	catch (AxisFault f) {
-	    System.err.println(f.getClass().getName());
-	    System.err.println("AxisFault Error in Create: " + f);
-	    System.exit(20);
-	}
-	catch (Exception f) {
-	    System.err.println(f.getClass().getName());
 	    System.err.println("Error in Create: " + f);
 	    System.exit(20);
 	}
+
+	// Tell the user we're underway
 	ExperimentLabels createLabels = 
 	    new ExperimentLabels(createResp.getExperimentID());
-	System.out.println("New success: " + createLabels.getLocalname()
-		+ "(" + createLabels.getFedid() + ") "
+	System.out.println("Success: " + createLabels.getLocalname()
+		+ " (" + createLabels.getFedid() + ") "
 		+ createResp.getExperimentStatus().getValue());
     }
Index: axis/FeddCommand.java
===================================================================
--- axis/FeddCommand.java	(revision 9f8dbc1776d1817ba1c1d00011f4f36f1f4a1e36)
+++ axis/FeddCommand.java	(revision 709306c47a20c1cc91acbe74a4f7b5051ea8035e)
@@ -1,20 +1,45 @@
+// WSDL generated types and port
 import edu.isi.www.fedd_types.*;
 import edu.isi.www.fedd_wsdl.*;
+
+// The usual suspects
 import java.net.*;
 import java.util.*;
 
-import net.deterlab.isi.XTrustProvider;
-import net.deterlab.isi.Fedid;
+// The Fedid and XTrustManager classes
+import net.deterlab.isi.*;
 
+// SSL manipulations and a couple Exceptions
 import javax.net.ssl.*;
+import javax.xml.rpc.*;
 
+/**
+ * Base class that all the example programs are derived from.  It holds
+ * routines that several classes use, including some key routines to massage
+ * java's security model closer to fedd's.
+ */
 public class FeddCommand {
 
+    // SetUpSecurity is defined below. This is necessary stuff, and putting it
+    // here guarantees that it's always called before main.
     static { setUpSecurity(); }
 
+    /**
+     * Parse out an experiment name from a return value.  Several fedd
+     * responses identify the experiment that was operated on (or created) by
+     * both a human-readable name and a fedid.  This class scans through the
+     * array of IDTypes returned and keeps the fedid and localname (mnemonic
+     * name) returned.
+     */
     static class ExperimentLabels {
+	/** The fedid */
 	protected String fedid;
+	/** The localname */
 	protected String localname;
 
+	/**
+	 * Construct the class - i.e., parse the array
+	 * @param experimentID an array of IDTypes holding the synonymous names
+	 */
 	public ExperimentLabels(IDType[] experimentID) {
 	    fedid = null;
@@ -34,8 +59,22 @@
 	    }
 	}
+	/**
+	 * Return the fedid
+	 * @return the fedid
+	 */
 	String getFedid() { return fedid; }
+	/**
+	 * Return the localname
+	 * @return the localname
+	 */
 	String getLocalname() { return localname; }
     }
 
+    /**
+     * This magic convinces the SSL routines to accept self-signed certificates
+     * from the server (fedd) and points the SSL routines at the local
+     * keystore.  Other applications may move the keystore assignment, but the
+     * XTrustProvider call is always necessary.
+     */
     public static void setUpSecurity() {
 	/* This magic turns off certificate chain checking. */
@@ -52,4 +91,11 @@
     }
 
+    /**
+     * Clear the SSL session cache.  Java aggressively reuses SSL sessions, and
+     * it confuses fedd greatly - connections drop.  This routine invalidates
+     * all the existing sessions.  Necessary when you will make more than one
+     * call.  This is also called by getPort, so getting a new port before each
+     * new call will also atomize the sessions.
+     */
     static public void clearSSLSessionCache() {
 	try { 
@@ -60,5 +106,4 @@
 		SSLSession s = ssctxt.getSession(e.nextElement());
 		s.invalidate();
-		System.err.println("invalidated " + s);
 	    }
 	}
@@ -66,6 +111,14 @@
     }
 
-    public static FeddPortType getPort(String server) throws 
-	    javax.xml.rpc.ServiceException, java.net.MalformedURLException {
+    /**
+     * Get a new FeddPortType on which requests can be made.  The server to
+     * contact is passed as a string.
+     * @param server a String containing the server URL
+     * @return a FeddPortType to talk to.
+     * @throws ServiceException if the services/server can't be found
+     * @throws MalformedURLException if the URL is bad
+     */
+    public static FeddPortType getPort(String server) 
+	    throws ServiceException, MalformedURLException {
 	/* 
 	 * Boilerplate web services access stuff.
Index: axis/MultiStatus.java
===================================================================
--- axis/MultiStatus.java	(revision 9f8dbc1776d1817ba1c1d00011f4f36f1f4a1e36)
+++ axis/MultiStatus.java	(revision 709306c47a20c1cc91acbe74a4f7b5051ea8035e)
@@ -1,17 +1,15 @@
+// WSDL generated classes
 import edu.isi.www.fedd_types.*;
 import edu.isi.www.fedd_wsdl.*;
-import java.net.URL;
-import net.deterlab.isi.XTrustProvider;
-import net.deterlab.isi.Fedid;
+
+// The fault thrown by failed commands
+import org.apache.axis.AxisFault;
 
 class MultiStatus extends FeddCommand {
 
     /**
-     * Dummy program to test an AXIS fedd implementation generated from the
-     * WSDL and run by axis.
-     * It just calls terminate with a dummy id as a local name (which can be
-     * supplied on the command line and reprints the localname that the server
-     * replies with.  A client certificate muct exist in the local keystore
-     * file with the given password. 
+     * Get the list of active experiments created by this user.  The list has
+     * the same format as fedd_multistatus.py - name:fedid:state.  If no
+     * experiments are active, a line to that effect is printed.
      */
     public static void main(String args[]) throws 
@@ -20,19 +18,17 @@
 	
 	FeddPortType port = getPort("https://users.isi.deterlab.net:23235");
-	/*
-	 * The various parts of the MultiInfo message and response
-	 */
-
 	MultiInfoRequestType req = new MultiInfoRequestType();
 	MultiInfoResponseType resp = null;
 
+	// Make the call: the request is basically empty
 	try {
-	    /* Build the message and make the call */
 	    resp = port.multiInfo(req);
 	}
-	catch (Exception e) {
-	    System.out.println(e);
-	    System.exit(0);
+	catch (AxisFault e) {
+	    System.out.println("Request failed: " + e);
+	    System.exit(20);
 	}
+
+	// Parse out the response and print the lines.
 	if (resp.getInfo() != null) {
 	    for (InfoResponseType info: resp.getInfo()) {
Index: axis/Terminate.java
===================================================================
--- axis/Terminate.java	(revision 9f8dbc1776d1817ba1c1d00011f4f36f1f4a1e36)
+++ axis/Terminate.java	(revision 709306c47a20c1cc91acbe74a4f7b5051ea8035e)
@@ -1,30 +1,20 @@
+// WSDL generated classes
 import edu.isi.www.fedd_types.*;
 import edu.isi.www.fedd_wsdl.*;
-import java.net.URL;
-import net.deterlab.isi.XTrustProvider;
+
+// The fault thrown by failed commands
+import org.apache.axis.AxisFault;
 
 class Terminate extends FeddCommand {
     /**
-     * Dummy program to test an AXIS fedd implementation generated from the
-     * WSDL and run by axis.
-     * It just calls terminate with a dummy id as a local name (which can be
-     * supplied on the command line and reprints the localname that the server
-     * replies with.  A client certificate muct exist in the local keystore
-     * file with the given password. 
+     * Terminate the experiment with the menmonic name given on the command
+     * line.
      */
     public static void main(String args[]) throws 
 	    javax.xml.rpc.ServiceException, java.net.MalformedURLException,
 	    java.rmi.RemoteException {
-	
-	/* 
-	 * Boilerplate web services access stuff.
-	 */
+
+	// Get the port and construct the (simple) request.
 	FeddPortType port = getPort("https://users.isi.deterlab.net:23235");
-	setUpSecurity();
-
-	/*
-	 * The various parts of the Terminate message and response
-	 */
-
 	TerminateRequestType req = new TerminateRequestType(
 		new IDType(null, null, null, args[0], null), 
@@ -37,5 +27,5 @@
 	    resp = port.terminate(req);
 	}
-	catch (FaultType f) {
+	catch (AxisFault f) {
 	    System.err.println("Error in Terminate: " + f);
 	    System.exit(20);
