Index: java/GraphTest.java
===================================================================
--- java/GraphTest.java	(revision f25a7ffcb99a7f475cb3e6e2e5341f5c7be4c970)
+++ java/GraphTest.java	(revision d69593ce0c5640e3248d4afcfaff92abbe6cea16)
@@ -66,5 +66,5 @@
 	    if ( c.hasCertificate()) {
 		c.write(fn + n++ + suf);
-		ids.add(c.getID());
+		ids.add(c.issuer());
 	    }
 	}
Index: java/net/deterlab/abac/Context.java
===================================================================
--- java/net/deterlab/abac/Context.java	(revision f25a7ffcb99a7f475cb3e6e2e5341f5c7be4c970)
+++ java/net/deterlab/abac/Context.java	(revision d69593ce0c5640e3248d4afcfaff92abbe6cea16)
@@ -592,5 +592,5 @@
 	    c.write(z);
 	    z.closeEntry();
-	    if ( c.getID() != null && !allIDs) ids.add(c.getID());
+	    if ( c.issuer() != null && !allIDs) ids.add(c.issuer());
 	}
 	for (Identity i: ids) {
Index: java/net/deterlab/abac/Credential.java
===================================================================
--- java/net/deterlab/abac/Credential.java	(revision f25a7ffcb99a7f475cb3e6e2e5341f5c7be4c970)
+++ java/net/deterlab/abac/Credential.java	(revision d69593ce0c5640e3248d4afcfaff92abbe6cea16)
@@ -26,8 +26,8 @@
     protected static String authKeyOID = "2.5.29.35";
 
-    private Role m_head;
-    private Role m_tail;
-    private X509V2AttributeCertificate ac;
-    private Identity id;
+    protected Role m_head;
+    protected Role m_tail;
+    protected X509V2AttributeCertificate ac;
+    protected Identity id;
 
     /**
@@ -85,5 +85,5 @@
         load_roles();
 
-	if (!id.getKeyID().equals(m_head.issuer_part()))
+	if (!id.getKeyID().equals(m_head.principal()))
 	    throw new InvalidKeyException("Unknown identity");
     }
@@ -127,7 +127,7 @@
 
 	gen.setIssuer(new AttributeCertificateIssuer(
-		    new X509Principal("CN="+m_head.issuer_part())));
+		    new X509Principal("CN="+m_head.principal())));
 	gen.setHolder(new AttributeCertificateHolder(
-		    new X509Principal("CN="+m_head.issuer_part())));
+		    new X509Principal("CN="+m_head.principal())));
 	gen.setNotAfter(new Date(System.currentTimeMillis() 
 		    + 3600 * 1000 * 24 * 365));
@@ -241,5 +241,7 @@
     public boolean hasCertificate() { return ac != null; }
 
-    public Identity getID() { return id; }
+    public Identity issuer() { return id; }
+    public X509Certificate issuerCert() { return id.getCertificate(); }
+    public X509V2AttributeCertificate attributeCert() { return ac; }
 
 
Index: java/net/deterlab/abac/Role.java
===================================================================
--- java/net/deterlab/abac/Role.java	(revision f25a7ffcb99a7f475cb3e6e2e5341f5c7be4c970)
+++ java/net/deterlab/abac/Role.java	(revision d69593ce0c5640e3248d4afcfaff92abbe6cea16)
@@ -9,9 +9,10 @@
  */
 public class Role implements Comparable {
-    private String m_string;
-    private String[] m_parts;
-    private String m_A_r1, m_r2;
-    private String m_prefix;
-    private Role[] m_prereqs;
+    protected String m_string;
+    protected String[] m_parts;
+    protected String m_A_r1;
+    protected String m_r2;
+    protected String m_prefix;
+    protected Role[] m_prereqs;
 
     /**
@@ -50,4 +51,17 @@
     public Role(String s, Context c) {
 	this(c.expandKeyID(s));
+    }
+
+    public Role(Role r) {
+	m_string = r.m_string;
+	m_A_r1 = r.m_A_r1;
+	m_r2 = r.m_r2;
+	m_prefix = r.m_prefix;
+	m_parts = new String[r.m_parts.length];
+	for (int i = 0; i < r.m_parts.length; i++) 
+	    m_parts[i] = r.m_parts[i];
+	m_prereqs = new Role[m_prereqs.length];
+	for (int i = 0; i < r.m_prereqs.length; i++) 
+	    m_prereqs[i] = new Role(r.m_prereqs[i]);
     }
 
@@ -126,8 +140,7 @@
     }
 
-    /**
-     * Returns an issuer, only the first element.
-     */
-    public String issuer_part() { return m_parts[0]; }
+    public String principal() { return m_parts.length > 0 ? m_parts[0] : null; }
+    public String role_name() { return m_parts.length > 1 ? m_parts[1] : null; }
+    public String linked_role() { return A_r1(); }
 
     /**
