diff --git a/projects/cadcAccessControl-Server/build.xml b/projects/cadcAccessControl-Server/build.xml
index 12e688469aee1444d7027bef89f048af9de33f88..39cce90c8e2f2e8c6a52777adad23ec353c5d8f0 100644
--- a/projects/cadcAccessControl-Server/build.xml
+++ b/projects/cadcAccessControl-Server/build.xml
@@ -139,7 +139,7 @@
   <property name="testingJars"
             value="${lib.commons-logging}:${dev.junit}:${dev.jsonassert}:${dev.httpunit}:${dev.easyMock}:${dev.selenium.server}:${dev.objenesis}:${lib.js}:${lib.nekoHTML}:${lib.xerces}"/>
 
-  <target name="test" depends="compile,compile-test">
+  <target name="single-test" depends="compile,compile-test">
     <echo message="Running test suite..." />
     <junit printsummary="yes" haltonfailure="yes" fork="yes">
       <classpath>
@@ -148,8 +148,7 @@
         <pathelement path="${jars}:${testingJars}"/>
       </classpath>
       <sysproperty key="ca.nrc.cadc.util.PropertiesReader.dir" value="test"/>
-      <test name="ca.nrc.cadc.ac.server.ldap.LdapUserDAOTest" />
-      <test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" />
+      <test name="ca.nrc.cadc.ac.server.web.users.GetUserListActionTest" />
       <formatter type="plain" usefile="false" />
     </junit>
   </target>
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java
index 4e588eb5646c2744957c7589f591f8d5ce3ebc68..71ddf32316e6de250ab5ef5b9a9c2afdb26657b6 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java
@@ -311,7 +311,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         {
             final Filter filter = Filter.createPresenceFilter("cn");
             final String [] attributes = new String[] {"cn", "nsaccountlock"};
-            final List<String> groupNames = new ArrayList<String>();
+            final Collection<String> groupNames = new ArrayList<String>();
             final long begin = System.currentTimeMillis();
 
             final SearchResult searchResult =
@@ -973,8 +973,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
 
         Group group = new Group(searchResult.getAttributeValue("cn"),
                                 userPersist.getX500User(
-                                        new DN(searchResult.getAttributeValue(
-                                                "owner"))));
+                                    new DN(searchResult.getAttributeValue(
+                                        "owner"))));
         group.description = searchResult.getAttributeValue("description");
         return group;
     }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
index 3150e2768ae61c800546b76209a37f3e2378e15c..772c6531a7cdfc147731f570795620cbde4dd3c6 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
@@ -359,8 +359,8 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                 .getName());
             addAttribute(attributes, LDAP_DISTINGUISHED_NAME, userDN
                 .toNormalizedString());
-            addAttribute(attributes, LADP_USER_PASSWORD, userRequest
-                    .getPassword());
+            addAttribute(attributes, LADP_USER_PASSWORD,
+                String.valueOf(userRequest.getPassword()));
 
             for (UserDetails details : user.details)
             {
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ACSearchRunner.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ACSearchRunner.java
index a6409ad49a03dfa8167385d66256577d3ae235f3..f576ec6ba47de6cf4cff2ee3e8fb394d142e3a32 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ACSearchRunner.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ACSearchRunner.java
@@ -74,7 +74,7 @@ import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.server.GroupPersistence;
 import ca.nrc.cadc.ac.server.PluginFactory;
 import ca.nrc.cadc.ac.server.RequestValidator;
-import ca.nrc.cadc.ac.xml.GroupsWriter;
+import ca.nrc.cadc.ac.xml.GroupListWriter;
 import ca.nrc.cadc.auth.AuthenticationUtil;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
@@ -236,7 +236,8 @@ public class ACSearchRunner implements JobRunner
                 groups = new ArrayList<Group>();
             }
             syncOut.setResponseCode(HttpServletResponse.SC_OK);
-            GroupsWriter.write(groups, syncOut.getOutputStream());
+            GroupListWriter groupListWriter = new GroupListWriter();
+            groupListWriter.write(groups, syncOut.getOutputStream());
             
             // Mark the Job as completed.
 //            jobUpdater.setPhase(job.getID(), ExecutionPhase.EXECUTING, 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
similarity index 98%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsAction.java
rename to projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
index 4ef1811573d47b135823e0e584ae9b2ace14b720..d9819f9426be7f9287d8bcf5b31ea439e5864872 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
@@ -90,14 +90,14 @@ import ca.nrc.cadc.ac.server.PluginFactory;
 import ca.nrc.cadc.ac.server.UserPersistence;
 import ca.nrc.cadc.net.TransientException;
 
-public abstract class GroupsAction
+public abstract class AbstractGroupAction
     implements PrivilegedExceptionAction<Object>
 {
-    private static final Logger log = Logger.getLogger(GroupsAction.class);
+    private static final Logger log = Logger.getLogger(AbstractGroupAction.class);
     protected GroupLogInfo logInfo;
     protected HttpServletResponse response;
 
-    GroupsAction(GroupLogInfo logInfo)
+    AbstractGroupAction(GroupLogInfo logInfo)
     {
         this.logInfo = logInfo;
     }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddGroupMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddGroupMemberAction.java
index 61669fa27d74b9f372b10fe30c4225c1e63d6a6b..cbb4ce4bd8b5536deec740c55b0a94846d9d820c 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddGroupMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddGroupMemberAction.java
@@ -74,7 +74,7 @@ import ca.nrc.cadc.ac.server.GroupPersistence;
 import java.util.ArrayList;
 import java.util.List;
 
-public class AddGroupMemberAction extends GroupsAction
+public class AddGroupMemberAction extends AbstractGroupAction
 {
     private final String groupName;
     private final String groupMemberName;
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java
index cdf6093abea691a7412e1fd0a4a6bacd36c12cd4..b30888024d8ecab5db3b06dbcd2c3432976f6fc8 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AddUserMemberAction.java
@@ -77,7 +77,7 @@ import java.security.Principal;
 import java.util.ArrayList;
 import java.util.List;
 
-public class AddUserMemberAction extends GroupsAction
+public class AddUserMemberAction extends AbstractGroupAction
 {
     private final String groupName;
     private final String userID;
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java
index f282d722627e25796756e8921ae77ca2fb4f3940..f349a9c82e7d549f0deeef04985d9b81af6ca17f 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/CreateGroupAction.java
@@ -78,7 +78,7 @@ import ca.nrc.cadc.ac.server.GroupPersistence;
 import ca.nrc.cadc.ac.xml.GroupReader;
 import ca.nrc.cadc.ac.xml.GroupWriter;
 
-public class CreateGroupAction extends GroupsAction
+public class CreateGroupAction extends AbstractGroupAction
 {
     private final InputStream inputStream;
 
@@ -92,10 +92,12 @@ public class CreateGroupAction extends GroupsAction
         throws Exception
     {
         GroupPersistence groupPersistence = getGroupPersistence();
-        Group group = GroupReader.read(this.inputStream);
+        GroupReader groupReader = new GroupReader();
+        Group group = groupReader.read(this.inputStream);
         Group newGroup = groupPersistence.addGroup(group);
         this.response.setContentType("application/xml");
-        GroupWriter.write(newGroup, this.response.getOutputStream());
+        GroupWriter groupWriter = new GroupWriter();
+        groupWriter.write(newGroup, this.response.getOutputStream());
 
         List<String> addedMembers = null;
         if ((newGroup.getUserMembers().size() > 0) || (newGroup.getGroupMembers().size() > 0))
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/DeleteGroupAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/DeleteGroupAction.java
index 2c96f279f30a5108de5be505761094a2c4e5bf9a..6459b9d5a7c8e0f50a24bc0217c6fe32b763f99d 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/DeleteGroupAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/DeleteGroupAction.java
@@ -74,7 +74,7 @@ import ca.nrc.cadc.ac.Group;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.server.GroupPersistence;
 
-public class DeleteGroupAction extends GroupsAction
+public class DeleteGroupAction extends AbstractGroupAction
 {
     private final String groupName;
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupAction.java
index 3d7d9646f6692d46f3c76e2943702a7d55707bb2..6e3b3e64374ecc502b480a339478bf75257b7fde 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupAction.java
@@ -71,7 +71,7 @@ import ca.nrc.cadc.ac.Group;
 import ca.nrc.cadc.ac.server.GroupPersistence;
 import ca.nrc.cadc.ac.xml.GroupWriter;
 
-public class GetGroupAction extends GroupsAction
+public class GetGroupAction extends AbstractGroupAction
 {
     private final String groupName;
 
@@ -87,7 +87,8 @@ public class GetGroupAction extends GroupsAction
         GroupPersistence groupPersistence = getGroupPersistence();
         Group group = groupPersistence.getGroup(this.groupName);
         this.response.setContentType("application/xml");
-        GroupWriter.write(group, this.response.getOutputStream());
+        GroupWriter groupWriter = new GroupWriter();
+        groupWriter.write(group, this.response.getOutputStream());
         return null;
     }
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupNamesAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupNamesAction.java
index a62ef9526d1ff961f6f9b0a88ea82283762f061c..7867869cd335b2dfe23bb856c65e3df232fd2469 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupNamesAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GetGroupNamesAction.java
@@ -76,7 +76,7 @@ import org.apache.log4j.Logger;
 
 import ca.nrc.cadc.ac.server.GroupPersistence;
 
-public class GetGroupNamesAction extends GroupsAction
+public class GetGroupNamesAction extends AbstractGroupAction
 {
     
     private static final Logger log = Logger.getLogger(GetGroupNamesAction.class);
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupServlet.java
similarity index 96%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsServlet.java
rename to projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupServlet.java
index cd4682325e14892bdb73c8cd96c7ed1782368730..f7e10f54b59be431c7d8e7315ddae07041f3d67c 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsServlet.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupServlet.java
@@ -79,9 +79,9 @@ import org.apache.log4j.Logger;
 
 import ca.nrc.cadc.auth.AuthenticationUtil;
 
-public class GroupsServlet extends HttpServlet
+public class GroupServlet extends HttpServlet
 {
-    private static final Logger log = Logger.getLogger(GroupsServlet.class);
+    private static final Logger log = Logger.getLogger(GroupServlet.class);
 
     /**
      * Create a GroupAction and run the action safely.
@@ -96,7 +96,7 @@ public class GroupsServlet extends HttpServlet
             log.info(logInfo.start());
             Subject subject = AuthenticationUtil.getSubject(request);
             logInfo.setSubject(subject);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, logInfo);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, logInfo);
             action.doAction(subject, response);
         }
         catch (IllegalArgumentException e)
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionFactory.java
index c2aaf942be82e190f33b7f9e1f7cb40aa6fafe97..a9bc0406ebf363626025eb93b5fe18c5fa860626 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionFactory.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionFactory.java
@@ -82,10 +82,10 @@ public class GroupsActionFactory
 {
     private static final Logger log = Logger.getLogger(GroupsActionFactory.class);
 
-    static GroupsAction getGroupsAction(HttpServletRequest request, GroupLogInfo logInfo)
+    static AbstractGroupAction getGroupsAction(HttpServletRequest request, GroupLogInfo logInfo)
         throws IOException
     {
-        GroupsAction action = null;
+        AbstractGroupAction action = null;
         String method = request.getMethod();
         String path = request.getPathInfo();
         log.debug("method: " + method);
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java
index 444e335dc3594ec7543872a5f77db25ef0cc4c32..040a898afbdf5113d7931f82b6aa9f40f7d00196 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/ModifyGroupAction.java
@@ -77,7 +77,7 @@ import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.server.GroupPersistence;
 import ca.nrc.cadc.ac.xml.GroupReader;
 
-public class ModifyGroupAction extends GroupsAction
+public class ModifyGroupAction extends AbstractGroupAction
 {
     private final String groupName;
     private final String request;
@@ -96,7 +96,8 @@ public class ModifyGroupAction extends GroupsAction
         throws Exception
     {
         GroupPersistence groupPersistence = getGroupPersistence();
-        Group group = GroupReader.read(this.inputStream);
+        GroupReader groupReader = new GroupReader();
+        Group group = groupReader.read(this.inputStream);
         Group oldGroup = groupPersistence.getGroup(this.groupName);
         groupPersistence.modifyGroup(group);
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberAction.java
index a05d17f93d73a061e96bb44975b3f68548b3b7c5..bb755731a22c2e21998dd0416db394aee52baed2 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveGroupMemberAction.java
@@ -74,7 +74,7 @@ import ca.nrc.cadc.ac.server.GroupPersistence;
 import java.util.ArrayList;
 import java.util.List;
 
-public class RemoveGroupMemberAction extends GroupsAction
+public class RemoveGroupMemberAction extends AbstractGroupAction
 {
     private final String groupName;
     private final String groupMemberName;
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java
index 20dcf8b4a32af6119d4033ea5b72db0389218ba1..e0ecc8800c67f5106cfcbb773bff04446b71d57b 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/RemoveUserMemberAction.java
@@ -77,7 +77,7 @@ import java.security.Principal;
 import java.util.ArrayList;
 import java.util.List;
 
-public class RemoveUserMemberAction extends GroupsAction
+public class RemoveUserMemberAction extends AbstractGroupAction
 {
     private final String groupName;
     private final String userID;
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
similarity index 89%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java
rename to projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
index 39ca1313e2f1b4b283628ec53a640f32a82e4911..d0d59b5423f813a303840a4f500eda509964d88e 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
@@ -72,8 +72,16 @@ import ca.nrc.cadc.ac.PersonalDetails;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.UserRequest;
+import ca.nrc.cadc.ac.json.JsonUserListWriter;
+import ca.nrc.cadc.ac.json.JsonUserReader;
+import ca.nrc.cadc.ac.json.JsonUserRequestReader;
+import ca.nrc.cadc.ac.json.JsonUserWriter;
 import ca.nrc.cadc.ac.server.PluginFactory;
 import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.ac.xml.UserListWriter;
+import ca.nrc.cadc.ac.xml.UserReader;
+import ca.nrc.cadc.ac.xml.UserRequestReader;
+import ca.nrc.cadc.ac.xml.UserWriter;
 import ca.nrc.cadc.net.TransientException;
 import org.apache.log4j.Logger;
 
@@ -88,10 +96,10 @@ import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Map;
 
-public abstract class UsersAction
+public abstract class AbstractUserAction
     implements PrivilegedExceptionAction<Object>
 {
-    private static final Logger log = Logger.getLogger(UsersAction.class);
+    private static final Logger log = Logger.getLogger(AbstractUserAction.class);
     static final String DEFAULT_CONTENT_TYPE = "text/xml";
     static final String JSON_CONTENT_TYPE = "application/json";
 
@@ -102,7 +110,7 @@ public abstract class UsersAction
     private String redirectURLPrefix;
 
 
-    UsersAction(UserLogInfo logInfo)
+    AbstractUserAction(UserLogInfo logInfo)
     {
         this.logInfo = logInfo;
     }
@@ -236,12 +244,13 @@ public abstract class UsersAction
 
         if (acceptedContentType.equals(DEFAULT_CONTENT_TYPE))
         {
-            userRequest = ca.nrc.cadc.ac.xml.UserRequestReader.read(inputStream);
+            UserRequestReader requestReader = new UserRequestReader();
+            userRequest = requestReader.read(inputStream);
         }
         else if (acceptedContentType.equals(JSON_CONTENT_TYPE))
         {
-            userRequest =
-                    ca.nrc.cadc.ac.json.UserRequestReader.read(inputStream);
+            JsonUserRequestReader requestReader = new JsonUserRequestReader();
+            userRequest = requestReader.read(inputStream);
         }
         else
         {
@@ -269,11 +278,13 @@ public abstract class UsersAction
 
         if (acceptedContentType.equals(DEFAULT_CONTENT_TYPE))
         {
-            user = ca.nrc.cadc.ac.xml.UserReader.read(inputStream);
+            UserReader userReader = new UserReader();
+            user = userReader.read(inputStream);
         }
         else if (acceptedContentType.equals(JSON_CONTENT_TYPE))
         {
-            user = ca.nrc.cadc.ac.json.UserReader.read(inputStream);
+            JsonUserReader userReader = new JsonUserReader();
+            user = userReader.read(inputStream);
         }
         else
         {
@@ -299,11 +310,13 @@ public abstract class UsersAction
 
         if (acceptedContentType.equals(DEFAULT_CONTENT_TYPE))
         {
-            ca.nrc.cadc.ac.xml.UserWriter.write(user, writer);
+            UserWriter userWriter = new UserWriter();
+            userWriter.write(user, writer);
         }
         else if (acceptedContentType.equals(JSON_CONTENT_TYPE))
         {
-            ca.nrc.cadc.ac.json.UserWriter.write(user, writer);
+            JsonUserWriter userWriter = new JsonUserWriter();
+            userWriter.write(user, writer);
         }
     }
 
@@ -320,11 +333,13 @@ public abstract class UsersAction
 
         if (acceptedContentType.equals(DEFAULT_CONTENT_TYPE))
         {
-            ca.nrc.cadc.ac.xml.UsersWriter.write(users, writer);
+            UserListWriter userListWriter = new UserListWriter();
+            userListWriter.write(users, writer);
         }
         else if (acceptedContentType.equals(JSON_CONTENT_TYPE))
         {
-            ca.nrc.cadc.ac.json.UsersWriter.write(users, writer);
+            JsonUserListWriter userListWriter = new JsonUserListWriter();
+            userListWriter.write(users, writer);
         }
     }
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java
index 96ec4f6268f2ceb96ffe6e0e97ff743a29f867e0..4cefc087c65f2c6901981879b2386c2a093c6c67 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java
@@ -83,7 +83,7 @@ import java.security.Principal;
 import java.util.Set;
 
 
-public class CreateUserAction extends UsersAction
+public class CreateUserAction extends AbstractUserAction
 {
     private final InputStream inputStream;
 
@@ -98,12 +98,12 @@ public class CreateUserAction extends UsersAction
 
     public Object run() throws Exception
     {
+        UserRequest<Principal> userRequest = null;
         try
         {
             final UserPersistence<Principal> userPersistence =
                     getUserPersistence();
-            final UserRequest<Principal> userRequest =
-                    readUserRequest(this.inputStream);
+            userRequest = readUserRequest(this.inputStream);
             final User<Principal> newUser =
                     userPersistence.addUser(userRequest);
             final Set<HttpPrincipal> httpPrincipals =
@@ -131,6 +131,13 @@ public class CreateUserAction extends UsersAction
         {
             throw new IllegalArgumentException("Invalid input", e);
         }
+        finally
+        {
+            if (userRequest != null)
+            {
+                userRequest.clear();
+            }
+        }
 
         return null;
     }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/DeleteUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/DeleteUserAction.java
index 806e8f9812bec8751246ef1f7f8a84b8081a2d29..4f932b9cccc5cfea3936410a92c9fef33d66615f 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/DeleteUserAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/DeleteUserAction.java
@@ -72,7 +72,7 @@ import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.server.UserPersistence;
 import java.security.Principal;
 
-public class DeleteUserAction extends UsersAction
+public class DeleteUserAction extends AbstractUserAction
 {
     private final Principal userID;
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java
index 0d87074e50c61558ce4b2f18ea43e7c273e518f1..b126b70466c088d7912d3c742476c2285535a7a3 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserAction.java
@@ -74,7 +74,7 @@ import ca.nrc.cadc.ac.server.UserPersistence;
 import java.security.Principal;
 
 
-public class GetUserAction extends UsersAction
+public class GetUserAction extends AbstractUserAction
 {
     private final Principal userID;
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserListAction.java
similarity index 96%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java
rename to projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserListAction.java
index 008a8572ec167b146db84497e82df94e4d95aee0..ad60c91c1d400f1e419af3bcc59609661fc726fe 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUserListAction.java
@@ -75,12 +75,12 @@ import org.apache.log4j.Logger;
 import ca.nrc.cadc.ac.server.UserPersistence;
 
 
-public class GetUsersAction extends UsersAction
+public class GetUserListAction extends AbstractUserAction
 {
     
-    private static final Logger log = Logger.getLogger(GetUsersAction.class);
+    private static final Logger log = Logger.getLogger(GetUserListAction.class);
 
-    GetUsersAction(UserLogInfo logInfo)
+    GetUserListAction(UserLogInfo logInfo)
     {
         super(logInfo);
     }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java
index 1349d5744b6f72457fce6a0609307d0874c31b47..caba15d91eb4b70c55ee77cbef7ca90d84ba9d52 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java
@@ -79,7 +79,7 @@ import java.security.Principal;
 import java.util.Set;
 
 
-public class ModifyUserAction extends UsersAction
+public class ModifyUserAction extends AbstractUserAction
 {
     private final InputStream inputStream;
 
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java
similarity index 96%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java
rename to projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java
index 9333357cdd6723110d0750d682b4b8071f5713da..6bb9338b42989becd82656e7b6afb0ddec5d1f4d 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java
@@ -77,7 +77,6 @@ import ca.nrc.cadc.auth.OpenIdPrincipal;
 import ca.nrc.cadc.util.StringUtil;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.security.Principal;
 import javax.security.auth.x500.X500Principal;
 import javax.servlet.http.HttpServletRequest;
@@ -85,15 +84,15 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.log4j.Logger;
 
 
-public class UsersActionFactory
+public class UserActionFactory
 {
     private static final Logger log = Logger
-            .getLogger(UsersActionFactory.class);
+            .getLogger(UserActionFactory.class);
 
-    static UsersAction getUsersAction(HttpServletRequest request, UserLogInfo logInfo)
+    static AbstractUserAction getUsersAction(HttpServletRequest request, UserLogInfo logInfo)
             throws IOException
     {
-        UsersAction action = null;
+        AbstractUserAction action = null;
         String method = request.getMethod();
         String path = request.getPathInfo();
         log.debug("method: " + method);
@@ -124,7 +123,7 @@ public class UsersActionFactory
         {
             if (method.equals("GET"))
             {
-                action = new GetUsersAction(logInfo);
+                action = new GetUserListAction(logInfo);
             }
             else if (method.equals("PUT"))
             {
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java
similarity index 94%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java
rename to projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java
index c3f2e53c75821f6de8d170d5d1a02393196ca316..fd3cab4c0e8c0b97ce05ab00223c37559f57aa79 100644
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java
@@ -75,15 +75,14 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import ca.nrc.cadc.ac.UserAlreadyExistsException;
 import ca.nrc.cadc.util.StringUtil;
 import org.apache.log4j.Logger;
 
 import ca.nrc.cadc.auth.AuthenticationUtil;
 
-public class UsersServlet extends HttpServlet
+public class UserServlet extends HttpServlet
 {
-    private static final Logger log = Logger.getLogger(UsersServlet.class);
+    private static final Logger log = Logger.getLogger(UserServlet.class);
 
 
     /**
@@ -100,7 +99,7 @@ public class UsersServlet extends HttpServlet
             log.info(logInfo.start());
             Subject subject = AuthenticationUtil.getSubject(request);
             logInfo.setSubject(subject);
-            UsersAction action = UsersActionFactory.getUsersAction(request, logInfo);
+            AbstractUserAction action = UserActionFactory.getUsersAction(request, logInfo);
             action.setAcceptedContentType(getAcceptedContentType(request));
             action.doAction(subject, response);
         }
@@ -174,13 +173,13 @@ public class UsersServlet extends HttpServlet
         final String requestedContentType = request.getHeader("Accept");
 
         if (StringUtil.hasText(requestedContentType)
-            && requestedContentType.contains(UsersAction.JSON_CONTENT_TYPE))
+            && requestedContentType.contains(AbstractUserAction.JSON_CONTENT_TYPE))
         {
-            return UsersAction.JSON_CONTENT_TYPE;
+            return AbstractUserAction.JSON_CONTENT_TYPE;
         }
         else
         {
-            return UsersAction.DEFAULT_CONTENT_TYPE;
+            return AbstractUserAction.DEFAULT_CONTENT_TYPE;
         }
     }
 }
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
index 647af875c103090c284eb71cb4a507932d648264..4226915aa1437ea3c8242be4f80753f6ee9d77e9 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
@@ -149,7 +149,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         expected.details.add(new PersonalDetails("foo", "bar"));
 
         final UserRequest<HttpPrincipal> userRequest =
-                new UserRequest<HttpPrincipal>(expected, "123456");
+                new UserRequest<HttpPrincipal>(expected, "123456".toCharArray());
 
         Subject subject = new Subject();
         subject.getPrincipals().add(testUser.getUserID());
@@ -415,8 +415,8 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         // Create a test user with a known password
         final User<HttpPrincipal> testUser2;
         final String username = createUserID();
-        final String password = "foo";
-        final String newPassword = "bar";
+        final char[] password = "foo".toCharArray();
+        final char[] newPassword = "bar".toCharArray();
 
         HttpPrincipal principal = new HttpPrincipal(username);
         testUser2 = new User<HttpPrincipal>(principal);
@@ -454,7 +454,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
             {
                 try
                 {
-                    getUserDAO().doLogin(username, password);
+                    getUserDAO().doLogin(username, String.valueOf(password));
                 }
                 catch (Exception e)
                 {
@@ -473,7 +473,8 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
                 try
                 {
                     final LdapUserDAO<HttpPrincipal> userDAO = getUserDAO();
-                    userDAO.setPassword(testUser2, password, newPassword);
+                    userDAO.setPassword(testUser2, String.valueOf(password),
+                                        String.valueOf(newPassword));
                     fail("should throw exception if subject and user are not the same");
                 }
                 catch (Exception ignore){}
@@ -491,7 +492,8 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
                 try
                 {
                     final LdapUserDAO<HttpPrincipal> userDAO = getUserDAO();
-                    userDAO.setPassword(testUser2, password, newPassword);
+                    userDAO.setPassword(testUser2, String.valueOf(password),
+                                        String.valueOf(newPassword));
                 }
                 catch (Exception e)
                 {
@@ -510,7 +512,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
             {
                 try
                 {
-                    getUserDAO().doLogin(username, password);
+                    getUserDAO().doLogin(username, String.valueOf(password));
                 }
                 catch (Exception e)
                 {
@@ -528,7 +530,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         // Create a test user
         final User<HttpPrincipal> testUser2;
         final String username = createUserID();
-        final String password = "foo";
+        final char[] password = "foo".toCharArray();
 
         HttpPrincipal principal = new HttpPrincipal(username);
         testUser2 = new User<HttpPrincipal>(principal);
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupActionTest.java
similarity index 98%
rename from projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionTest.java
rename to projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupActionTest.java
index def8852585eaf9d5102a31ede3712bb7214504f0..ec7ea077197cf6d138eeb686ce502fb89db90cf0 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupsActionTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupActionTest.java
@@ -91,9 +91,9 @@ import static org.junit.Assert.*;
  *
  * @author jburke
  */
-public class GroupsActionTest
+public class AbstractGroupActionTest
 {
-    private final static Logger log = Logger.getLogger(GroupsActionTest.class);
+    private final static Logger log = Logger.getLogger(AbstractGroupActionTest.class);
     
     @BeforeClass
     public static void setUpClass()
@@ -237,7 +237,7 @@ public class GroupsActionTest
         }
     }
 
-    public class GroupsActionImpl extends GroupsAction
+    public class GroupsActionImpl extends AbstractGroupAction
     {
         Exception exception;
         
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupActionFactoryTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupActionFactoryTest.java
index 3a9b19ccb053c960256ea8c67cd32fe39dac6544..0f1cbfd5e4a586c7a2451035266d875b3d93d9bc 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupActionFactoryTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/groups/GroupActionFactoryTest.java
@@ -95,7 +95,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getPathInfo()).andReturn("groupName/groupMembers/groupToAdd");
             EasyMock.expect(request.getMethod()).andReturn("PUT");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof AddGroupMemberAction);
         }
@@ -116,7 +116,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getParameter("idType")).andReturn("x509");
             EasyMock.expect(request.getMethod()).andReturn("PUT");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof AddUserMemberAction);
         }
@@ -137,7 +137,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getMethod()).andReturn("PUT");
             EasyMock.expect(request.getInputStream()).andReturn(null);
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof CreateGroupAction);
         }
@@ -157,7 +157,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getPathInfo()).andReturn("groupName");
             EasyMock.expect(request.getMethod()).andReturn("DELETE");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof DeleteGroupAction);
         }
@@ -177,7 +177,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getPathInfo()).andReturn("groupName");
             EasyMock.expect(request.getMethod()).andReturn("GET");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof GetGroupAction);
         }
@@ -197,7 +197,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getPathInfo()).andReturn("");
             EasyMock.expect(request.getMethod()).andReturn("GET");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof GetGroupNamesAction);
         }
@@ -224,7 +224,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getServletPath()).andReturn("");
             EasyMock.expect(request.getInputStream()).andReturn(null);
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof ModifyGroupAction);
         }
@@ -244,7 +244,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getPathInfo()).andReturn("groupName/groupMembers/groupToRenove");
             EasyMock.expect(request.getMethod()).andReturn("DELETE");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof RemoveGroupMemberAction);
         }
@@ -265,7 +265,7 @@ public class GroupActionFactoryTest
             EasyMock.expect(request.getMethod()).andReturn("DELETE");
             EasyMock.expect(request.getParameter("idType")).andReturn("x509");
             EasyMock.replay(request);
-            GroupsAction action = GroupsActionFactory.getGroupsAction(request, null);
+            AbstractGroupAction action = GroupsActionFactory.getGroupsAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof RemoveUserMemberAction);
         }
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UsersActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/AbstractUserActionTest.java
similarity index 95%
rename from projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UsersActionTest.java
rename to projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/AbstractUserActionTest.java
index 9f68864b52147a94be6ea974d9ae7fd5cdfe178c..4da40b1e9e96f91df6c125264a61e298195b7ed4 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UsersActionTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/AbstractUserActionTest.java
@@ -68,16 +68,12 @@
  */
 package ca.nrc.cadc.ac.server.web.users;
 
-import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
-import ca.nrc.cadc.ac.server.UserPersistence;
-import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
 import ca.nrc.cadc.util.Log4jInit;
 
 import java.io.*;
 import java.security.AccessControlException;
-import java.security.Principal;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.log4j.Level;
@@ -85,17 +81,14 @@ import org.apache.log4j.Logger;
 
 import static org.easymock.EasyMock.*;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
-
 /**
  * @author jburke
  */
-public class UsersActionTest
+public class AbstractUserActionTest
 {
-    private final static Logger log = Logger.getLogger(UsersActionTest.class);
+    private final static Logger log = Logger.getLogger(AbstractUserActionTest.class);
 
     @BeforeClass
     public static void setUpClass()
@@ -190,7 +183,7 @@ public class UsersActionTest
         action.doAction(null, response);
     }
 
-    public class UsersActionImpl extends UsersAction
+    public class UsersActionImpl extends AbstractUserAction
     {
         Exception exception;
 
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java
index e116d69fc410b6e5c740bec4259f440753f03bd7..3b6c2826cc8b92f82a4036781f847c57b93e4db3 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserActionTest.java
@@ -68,7 +68,9 @@
 package ca.nrc.cadc.ac.server.web.users;
 
 import ca.nrc.cadc.ac.User;
+import ca.nrc.cadc.ac.json.JsonUserWriter;
 import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.ac.xml.UserWriter;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import org.junit.Test;
 
@@ -114,13 +116,11 @@ public class GetUserActionTest
 
         testSubject.doAction(null, mockResponse);
 
-        assertEquals("Wrong XML output.",
-                     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
-                     "<user>\r\n" +
-                     "  <userID>\r\n" +
-                     "    <identity type=\"HTTP\">CADCtest</identity>\r\n" +
-                     "  </userID>\r\n" +
-                     "</user>\r\n", writer.toString());
+        StringBuilder sb = new StringBuilder();
+        UserWriter userWriter = new UserWriter();
+        userWriter.write(user, sb);
+        assertEquals(sb.toString(), writer.toString());
+
         verify(mockResponse, mockUserPersistence);
     }
 
@@ -142,7 +142,7 @@ public class GetUserActionTest
             }
         };
 
-        testSubject.setAcceptedContentType(UsersAction.JSON_CONTENT_TYPE);
+        testSubject.setAcceptedContentType(AbstractUserAction.JSON_CONTENT_TYPE);
 
         final User<HttpPrincipal> user = new User<HttpPrincipal>(userID);
         final Writer writer = new StringWriter();
@@ -156,9 +156,11 @@ public class GetUserActionTest
         replay(mockResponse, mockUserPersistence);
         testSubject.doAction(null, mockResponse);
 
-        assertEquals("Wrong JSON output.",
-                     "{\"user\":{\"userID\":{\"identity\":{\"name\":\"CADCtest\",\"type\":\"HTTP\"}}}}",
-                     writer.toString());
+        StringBuilder sb = new StringBuilder();
+        JsonUserWriter userWriter = new JsonUserWriter();
+        userWriter.write(user, sb);
+        assertEquals(sb.toString(), writer.toString());
+
         verify(mockResponse, mockUserPersistence);
     }
 }
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java
similarity index 72%
rename from projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java
rename to projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java
index f1dc7a29aeb521d739a16325c62b97af3a83510a..c6f248cf846ca9b834671e28c445bc2aa1ddcde4 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserListActionTest.java
@@ -70,7 +70,9 @@ package ca.nrc.cadc.ac.server.web.users;
 
 
 import ca.nrc.cadc.ac.PersonalDetails;
+import ca.nrc.cadc.ac.json.JsonUserListWriter;
 import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.ac.xml.UserListWriter;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import org.apache.log4j.Level;
 
@@ -82,8 +84,6 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -97,7 +97,7 @@ import org.skyscreamer.jsonassert.JSONAssert;
  *
  * @author adriand
  */
-public class GetUsersActionTest
+public class GetUserListActionTest
 {
     @BeforeClass
     public static void setUpClass()
@@ -122,7 +122,7 @@ public class GetUsersActionTest
                             new PersonalDetails("USER", Integer.toString(i)));
         }
 
-        final GetUsersAction testSubject = new GetUsersAction(null)
+        final GetUserListAction testSubject = new GetUserListAction(null)
         {
             @Override
             UserPersistence<HttpPrincipal> getUserPersistence()
@@ -131,25 +131,26 @@ public class GetUsersActionTest
             }
         };
 
-        testSubject.setAcceptedContentType(UsersAction.JSON_CONTENT_TYPE);
+        testSubject.setAcceptedContentType(AbstractUserAction.JSON_CONTENT_TYPE);
 
-        final Writer writer = new StringWriter();
-        final PrintWriter printWriter = new PrintWriter(writer);
+        final Writer actualWriter = new StringWriter();
+        final PrintWriter actualPrintWriter = new PrintWriter(actualWriter);
 
         expect(mockUserPersistence.getUsers()).andReturn(
                 userEntries).once();
-        expect(mockResponse.getWriter()).andReturn(printWriter).once();
+        expect(mockResponse.getWriter()).andReturn(actualPrintWriter).once();
         mockResponse.setContentType("application/json");
         expectLastCall().once();
 
         replay(mockResponse, mockUserPersistence);
         testSubject.doAction(null, mockResponse);
 
-        final JSONArray expected =
-                new JSONArray("[{\"id\":\"USER_1\",\"firstName\":\"USER\",\"lastName\":\"1\"},{\"id\":\"USER_3\",\"firstName\":\"USER\",\"lastName\":\"3\"},{\"id\":\"USER_2\",\"firstName\":\"USER\",\"lastName\":\"2\"},{\"id\":\"USER_4\",\"firstName\":\"USER\",\"lastName\":\"4\"},{\"id\":\"USER_5\",\"firstName\":\"USER\",\"lastName\":\"5\"}]");
-        final JSONArray result = new JSONArray(writer.toString());
+        final Writer expectedWriter = new StringWriter();
+        final PrintWriter expectedPrintWriter = new PrintWriter(expectedWriter);
+        JsonUserListWriter userListWriter = new JsonUserListWriter();
+        userListWriter.write(userEntries, expectedPrintWriter);
+        JSONAssert.assertEquals(expectedWriter.toString(), actualWriter.toString(), false);
 
-        JSONAssert.assertEquals(expected, result, true);
         verify(mockResponse, mockUserPersistence);
     }
 
@@ -170,7 +171,7 @@ public class GetUsersActionTest
                             new PersonalDetails("USER", Integer.toString(i)));
         }
 
-        final GetUsersAction testSubject = new GetUsersAction(null)
+        final GetUserListAction testSubject = new GetUserListAction(null)
         {
             @Override
             UserPersistence<HttpPrincipal> getUserPersistence()
@@ -179,44 +180,24 @@ public class GetUsersActionTest
             }
         };
 
-        final Writer writer = new StringWriter();
-        final PrintWriter printWriter = new PrintWriter(writer);
+        final Writer actualWriter = new StringWriter();
+        final PrintWriter actualPrintWriter = new PrintWriter(actualWriter);
 
         expect(mockUserPersistence.getUsers()).andReturn(
                 userEntries).once();
-        expect(mockResponse.getWriter()).andReturn(printWriter).once();
+        expect(mockResponse.getWriter()).andReturn(actualPrintWriter).once();
         mockResponse.setContentType("text/xml");
         expectLastCall().once();
 
         replay(mockResponse, mockUserPersistence);
         testSubject.doAction(null, mockResponse);
 
-        final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
-                                "<users>\r\n" +
-                                "  <user id=\"USER_1\">\r\n" +
-                                "    <firstName>USER</firstName>\r\n" +
-                                "    <lastName>1</lastName>\r\n" +
-                                "  </user>\r\n" +
-                                "  <user id=\"USER_3\">\r\n" +
-                                "    <firstName>USER</firstName>\r\n" +
-                                "    <lastName>3</lastName>\r\n" +
-                                "  </user>\r\n" +
-                                "  <user id=\"USER_2\">\r\n" +
-                                "    <firstName>USER</firstName>\r\n" +
-                                "    <lastName>2</lastName>\r\n" +
-                                "  </user>\r\n" +
-                                "  <user id=\"USER_4\">\r\n" +
-                                "    <firstName>USER</firstName>\r\n" +
-                                "    <lastName>4</lastName>\r\n" +
-                                "  </user>\r\n" +
-                                "  <user id=\"USER_5\">\r\n" +
-                                "    <firstName>USER</firstName>\r\n" +
-                                "    <lastName>5</lastName>\r\n" +
-                                "  </user>\r\n" +
-                                "</users>\r\n";
-        final String result = writer.toString();
-
-        assertEquals("Wrong XML", expected, result);
+        final Writer expectedWriter = new StringWriter();
+        final PrintWriter expectedPrintWriter = new PrintWriter(expectedWriter);
+        UserListWriter userListWriter = new UserListWriter();
+        userListWriter.write(userEntries, expectedPrintWriter);
+        assertEquals("Wrong XML", expectedWriter.toString(), actualWriter.toString());
+
         verify(mockResponse, mockUserPersistence);
     }
 }
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java
index dde4aaa3110039f1d70db689e6309ffbbaaecff7..03276f20fe499d925de28ea8ba6a110888621a85 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java
@@ -68,20 +68,25 @@
 
 package ca.nrc.cadc.ac.server.web.users;
 
-
-import java.io.*;
-import java.security.Principal;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import ca.nrc.cadc.ac.PersonalDetails;
 import ca.nrc.cadc.ac.User;
+import ca.nrc.cadc.ac.json.JsonUserWriter;
 import ca.nrc.cadc.ac.server.UserPersistence;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import org.junit.Test;
-import static org.junit.Assert.*;
-import static org.easymock.EasyMock.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.Principal;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
 
 
 public class ModifyUserActionTest
@@ -89,19 +94,20 @@ public class ModifyUserActionTest
     @Test
     public void run() throws Exception
     {
-        final byte[] input =
-                "{\"user\":{\"userID\":{\"identity\":{\"name\":\"CADCtest\",\"type\":\"HTTP\"}},\"details\":[{\"userDetails\":{\"lastName\":\"Test\",\"firstName\":\"CADC\",\"email\":\"CADC.Test@nrc-cnrc.gc.ca\",\"type\":\"personalDetails\"}}],\"identities\":[{\"identity\":{\"name\":\"CADCtest\",\"type\":\"HTTP\"}}]}}"
-                        .getBytes();
+        final HttpPrincipal httpPrincipal = new HttpPrincipal("CADCtest");
+        User<Principal> expected = new User<Principal>(httpPrincipal);
+        expected.getIdentities().add(httpPrincipal);
+        final PersonalDetails pd = new PersonalDetails("CADC", "Test");
+        pd.email = "CADC.Test@nrc-cnrc.gc.ca";
+        expected.details.add(pd);
+
+        final StringBuilder sb = new StringBuilder();
+        final JsonUserWriter userWriter = new JsonUserWriter();
+        userWriter.write(expected, sb);
+
+        final byte[] input = sb.toString().getBytes();
         final InputStream inputStream = new ByteArrayInputStream(input);
 
-        // Should match the JSON above, without the e-mail modification.
-        final User<Principal> userObject =
-                new User<Principal>(new HttpPrincipal("CADCtest"));
-        final PersonalDetails personalDetail =
-                new PersonalDetails("CADC", "Test");
-        personalDetail.email = "CADC.Test@nrc-cnrc.gc.ca";
-        userObject.details.add(personalDetail);
-
         final HttpServletRequest mockRequest =
                 createMock(HttpServletRequest.class);
         final HttpServletResponse mockResponse =
@@ -113,14 +119,17 @@ public class ModifyUserActionTest
         final UserPersistence<Principal> mockUserPersistence =
                 createMock(UserPersistence.class);
 
-        expect(mockUserPersistence.modifyUser(userObject)).andReturn(
-                userObject).once();
+        expect(mockUserPersistence.modifyUser(expected)).andReturn(
+            expected).once();
 
         expect(mockRequest.getMethod()).andReturn("POST").once();
         expect(mockRequest.getRemoteAddr()).andReturn(requestURL).
                 once();
+        expect(mockRequest.getPathInfo()).andReturn("CADCtest").once();
 
-        mockResponse.sendRedirect(requestURL);
+        mockResponse.setStatus(HttpServletResponse.SC_OK);
+        expectLastCall().once();
+        mockResponse.setHeader("Location", "null/CADCtest?idType=HTTP");
         expectLastCall().once();
 
         mockResponse.setContentType("application/json");
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java
index 4241c015a6a3f7a2d21b0a0e41f0fac1ff37d45b..ec99f4c2284581c9e197caea1affd87932324da7 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java
@@ -95,7 +95,7 @@ public class UserActionFactoryTest
             EasyMock.expect(request.getMethod()).andReturn("PUT");
             EasyMock.expect(request.getInputStream()).andReturn(null);
             EasyMock.replay(request);
-            UsersAction action = UsersActionFactory.getUsersAction(request, null);
+            AbstractUserAction action = UserActionFactory.getUsersAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof CreateUserAction);
         }
@@ -116,7 +116,7 @@ public class UserActionFactoryTest
             EasyMock.expect(request.getMethod()).andReturn("DELETE");
             EasyMock.expect(request.getParameter("idType")).andReturn("sessionID");
             EasyMock.replay(request);
-            UsersAction action = UsersActionFactory.getUsersAction(request, null);
+            AbstractUserAction action = UserActionFactory.getUsersAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof DeleteUserAction);
         }
@@ -137,7 +137,7 @@ public class UserActionFactoryTest
             EasyMock.expect(request.getMethod()).andReturn("GET");
             EasyMock.expect(request.getParameter("idType")).andReturn("sessionID");
             EasyMock.replay(request);
-            UsersAction action = UsersActionFactory.getUsersAction(request, null);
+            AbstractUserAction action = UserActionFactory.getUsersAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof GetUserAction);
         }
@@ -157,9 +157,9 @@ public class UserActionFactoryTest
             EasyMock.expect(request.getPathInfo()).andReturn("");
             EasyMock.expect(request.getMethod()).andReturn("GET");
             EasyMock.replay(request);
-            UsersAction action = UsersActionFactory.getUsersAction(request, null);
+            AbstractUserAction action = UserActionFactory.getUsersAction(request, null);
             EasyMock.verify(request);
-            Assert.assertTrue("Wrong action", action instanceof GetUsersAction);
+            Assert.assertTrue("Wrong action", action instanceof GetUserListAction);
         }
         catch (Throwable t)
         {
@@ -185,7 +185,7 @@ public class UserActionFactoryTest
             EasyMock.expect(request.getInputStream()).andReturn(null);
             EasyMock.expect(request.getParameter("idType")).andReturn("sessionID");
             EasyMock.replay(request);
-            UsersAction action = UsersActionFactory.getUsersAction(request, null);
+            AbstractUserAction action = UserActionFactory.getUsersAction(request, null);
             EasyMock.verify(request);
             Assert.assertTrue("Wrong action", action instanceof ModifyUserAction);
         }
@@ -223,7 +223,7 @@ public class UserActionFactoryTest
                 EasyMock.replay(request);
                 try
                 {
-                    UsersActionFactory.getUsersAction(request, null);
+                    UserActionFactory.getUsersAction(request, null);
                     Assert.fail("Should have been a bad request: " + testRequest.method + " on " + testRequest.path);
                 }
                 catch (IllegalArgumentException e)
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UsersServletTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserServletTest.java
similarity index 88%
rename from projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UsersServletTest.java
rename to projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserServletTest.java
index 8e0a27f5b988c9cecbdcbd567d418c8825e4671e..3ab00e88c44a487a6367aec89f39d44ecb9142e9 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UsersServletTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserServletTest.java
@@ -8,14 +8,14 @@ import static org.easymock.EasyMock.*;
 import static org.junit.Assert.*;
 
 
-public class UsersServletTest
+public class UserServletTest
 {
     @Test
     public void getAcceptedContentTypeJSON() throws Exception
     {
         final HttpServletRequest mockRequest =
                 createMock(HttpServletRequest.class);
-        final UsersServlet testSubject = new UsersServlet();
+        final UserServlet testSubject = new UserServlet();
 
         expect(mockRequest.getHeader("Accept")).
                 andReturn("application/json").once();
@@ -33,7 +33,7 @@ public class UsersServletTest
     {
         final HttpServletRequest mockRequest =
                 createMock(HttpServletRequest.class);
-        final UsersServlet testSubject = new UsersServlet();
+        final UserServlet testSubject = new UserServlet();
 
         expect(mockRequest.getHeader("Accept")).andReturn(null).once();
 
diff --git a/projects/cadcAccessControl/build.xml b/projects/cadcAccessControl/build.xml
index 3296ce950c082b9ba95b90a8d517461a1d0ca14f..82f0e2c62be27a1548a145a699f0695183afbcd7 100644
--- a/projects/cadcAccessControl/build.xml
+++ b/projects/cadcAccessControl/build.xml
@@ -117,7 +117,7 @@
     
     <property name="testingJars" value="${build}/class:${jars}:${xerces}:${asm}:${cglib}:${easymock}:${junit}:${objenesis}" />
 
-    <target name="test" depends="compile,compile-test">
+    <target name="single-test" depends="compile,compile-test">
         <echo message="Running test suite..." />
         <junit printsummary="yes" haltonfailure="yes" fork="yes">
             <classpath>
@@ -125,10 +125,6 @@
                 <pathelement path="${build}/test/class"/>
                 <pathelement path="${testingJars}"/>
             </classpath>
-            <test name="ca.nrc.cadc.ac.json.GroupPropertyReaderWriterTest" />
-            <test name="ca.nrc.cadc.ac.json.UserDetailsReaderWriterTest" />
-            <test name="ca.nrc.cadc.ac.json.IdentityReaderWriterTest" />
-            <test name="ca.nrc.cadc.ac.json.UserReaderWriterTest" />
             <test name="ca.nrc.cadc.ac.json.GroupReaderWriterTest" />
             <formatter type="plain" usefile="false" />
         </junit>
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java
similarity index 100%
rename from projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserRequest.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserRequest.java
index d1c28cfac115e291be92c9fc60618f32de33113f..664b18d2a99d3f39e2927e9e7e6e89986371d2b6 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserRequest.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/UserRequest.java
@@ -74,15 +74,15 @@ import java.security.Principal;
 public class UserRequest<T extends Principal>
 {
     private User<T> user;
-    private String password;
+    private char[] password;
 
-    public UserRequest(final User<T> user, final String password)
+    public UserRequest(final User<T> user, final char[] password)
     {
         if (user == null)
         {
             throw new IllegalArgumentException("null user");
         }
-        if (password == null || password.isEmpty())
+        if (password == null || password.length == 0)
         {
             throw new IllegalArgumentException("null or empty password");
         }
@@ -95,11 +95,19 @@ public class UserRequest<T extends Principal>
         return this.user;
     }
 
-    public String getPassword()
+    public char[] getPassword()
     {
         return this.password;
     }
 
+    public void clear()
+    {
+        for (int i = 0; i < password.length; i++)
+        {
+            password[i] = '0';
+        }
+    }
+
     @Override
     public boolean equals(Object o)
     {
@@ -115,7 +123,6 @@ public class UserRequest<T extends Principal>
         UserRequest<?> that = (UserRequest<?>) o;
 
         return user.equals(that.user);
-
     }
 
     @Override
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
index 8f4eab02036b1155294d80566c74a434875ad142..bad17d1f5f80cee819082265ca7f344940ac14b1 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
@@ -68,7 +68,34 @@
  */
 package ca.nrc.cadc.ac.client;
 
-import java.io.*;
+import ca.nrc.cadc.ac.Group;
+import ca.nrc.cadc.ac.GroupAlreadyExistsException;
+import ca.nrc.cadc.ac.GroupNotFoundException;
+import ca.nrc.cadc.ac.Role;
+import ca.nrc.cadc.ac.User;
+import ca.nrc.cadc.ac.UserNotFoundException;
+import ca.nrc.cadc.ac.xml.GroupListReader;
+import ca.nrc.cadc.ac.xml.GroupReader;
+import ca.nrc.cadc.ac.xml.GroupWriter;
+import ca.nrc.cadc.auth.AuthenticationUtil;
+import ca.nrc.cadc.auth.HttpPrincipal;
+import ca.nrc.cadc.auth.SSLUtil;
+import ca.nrc.cadc.net.HttpDownload;
+import ca.nrc.cadc.net.HttpPost;
+import ca.nrc.cadc.net.HttpUpload;
+import ca.nrc.cadc.net.InputStreamWrapper;
+import ca.nrc.cadc.net.NetUtil;
+import org.apache.log4j.Logger;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSocketFactory;
+import javax.security.auth.Subject;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -84,27 +111,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-import javax.security.auth.Subject;
-
-import ca.nrc.cadc.ac.*;
-import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.util.StringUtil;
-import org.apache.log4j.Logger;
-
-import ca.nrc.cadc.ac.xml.GroupReader;
-import ca.nrc.cadc.ac.xml.GroupWriter;
-import ca.nrc.cadc.ac.xml.GroupsReader;
-import ca.nrc.cadc.auth.AuthenticationUtil;
-import ca.nrc.cadc.auth.SSLUtil;
-import ca.nrc.cadc.net.HttpDownload;
-import ca.nrc.cadc.net.HttpPost;
-import ca.nrc.cadc.net.HttpUpload;
-import ca.nrc.cadc.net.InputStreamWrapper;
-import ca.nrc.cadc.net.NetUtil;
-import org.json.JSONObject;
-
 
 /**
  * Client class for performing group searching and group actions
@@ -217,7 +223,7 @@ public class GMSClient
     {
         final URL usersListURL = new URL(this.baseURL + "/users");
         return new HttpDownload(usersListURL,
-                                new JSONUserListInputStreamWrapper(webUsers));
+                                new JsonUserListInputStreamWrapper(webUsers));
     }
 
     /**
@@ -242,7 +248,8 @@ public class GMSClient
         clearCache();
 
         StringBuilder groupXML = new StringBuilder();
-        GroupWriter.write(group, groupXML);
+        GroupWriter groupWriter = new GroupWriter();
+        groupWriter.write(group, groupXML);
         log.debug("createGroup: " + groupXML);
 
         byte[] bytes = groupXML.toString().getBytes("UTF-8");
@@ -283,7 +290,8 @@ public class GMSClient
         try
         {
             log.debug("createGroup returned: " + retXML);
-            return GroupReader.read(retXML);
+            GroupReader groupReader = new GroupReader();
+            return groupReader.read(retXML);
         }
         catch (Exception bug)
         {
@@ -339,7 +347,8 @@ public class GMSClient
         {
             String groupXML = new String(out.toByteArray(), "UTF-8");
             log.debug("getGroup returned: " + groupXML);
-            return GroupReader.read(groupXML);
+            GroupReader groupReader = new GroupReader();
+            return groupReader.read(groupXML);
         }
         catch (Exception bug)
         {
@@ -441,7 +450,8 @@ public class GMSClient
         clearCache();
 
         StringBuilder groupXML = new StringBuilder();
-        GroupWriter.write(group, groupXML);
+        GroupWriter groupWriter = new GroupWriter();
+        groupWriter.write(group, groupXML);
         log.debug("updateGroup: " + groupXML);
 
         HttpPost transfer = new HttpPost(updateGroupURL, groupXML.toString(),
@@ -482,7 +492,8 @@ public class GMSClient
         {
             String retXML = transfer.getResponseBody();
             log.debug("getGroup returned: " + retXML);
-            return GroupReader.read(retXML);
+            GroupReader groupReader = new GroupReader();
+            return groupReader.read(retXML);
         }
         catch (Exception bug)
         {
@@ -887,7 +898,8 @@ public class GMSClient
         {
             String groupsXML = new String(out.toByteArray(), "UTF-8");
             log.debug("getMemberships returned: " + groupsXML);
-            List<Group> groups = GroupsReader.read(groupsXML);
+            GroupListReader groupListReader = new GroupListReader();
+            List<Group> groups = groupListReader.read(groupsXML);
             setCachedGroups(userID, groups, role);
             return groups;
         }
@@ -1004,7 +1016,8 @@ public class GMSClient
         {
             String groupsXML = new String(out.toByteArray(), "UTF-8");
             log.debug("getMembership returned: " + groupsXML);
-            List<Group> groups = GroupsReader.read(groupsXML);
+            GroupListReader groupListReader = new GroupListReader();
+            List<Group> groups = groupListReader.read(groupsXML);
             if (groups.size() == 0)
             {
                 return null;
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java
index 8e3a47447965467f2f822dc5a532fff1ab0571a0..f00b0aeef2821f4740ae2eab7130b33d0001009f 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java
@@ -82,15 +82,15 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.List;
 
-public class JSONUserListInputStreamWrapper implements InputStreamWrapper
+public class JsonUserListInputStreamWrapper implements InputStreamWrapper
 {
     private static final Logger LOGGER = Logger
-            .getLogger(JSONUserListInputStreamWrapper.class);
+            .getLogger(JsonUserListInputStreamWrapper.class);
     private final List<User<HttpPrincipal>> output;
 
 
-    public JSONUserListInputStreamWrapper(
-            final List<User<HttpPrincipal>> output)
+    public JsonUserListInputStreamWrapper(
+        final List<User<HttpPrincipal>> output)
     {
         this.output = output;
     }
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/GroupReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java
similarity index 96%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/GroupReader.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java
index f726b87a5ea426ffd94bbf914b1da5124bb533ee..9d8055828d911f509543906fd9106ba9f92d706e 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/GroupReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupReader.java
@@ -87,7 +87,7 @@ import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.Scanner;
 
-public class GroupReader
+public class JsonGroupReader
 {
     /**
      * Construct a Group from a InputStream.
@@ -186,7 +186,7 @@ public class GroupReader
         {
             JSONObject ownerObject = groupObject.getJSONObject("owner");
             JSONObject userObject = ownerObject.getJSONObject("user");
-            user = UserReader.parseUser(userObject);
+            user = JsonUserReader.parseUser(userObject);
         }
 
         Group group = new Group(groupID, user);
@@ -221,7 +221,7 @@ public class GroupReader
             {
                 JSONObject propertiesObject = propertiesArray.getJSONObject(i);
                 JSONObject propertyObject = propertiesObject.getJSONObject("property");
-                group.getProperties().add(GroupPropertyReader.read(propertyObject));
+                group.getProperties().add(JsonGroupPropertyReader.read(propertyObject));
             }
         }
 
@@ -245,7 +245,7 @@ public class GroupReader
             {
                 JSONObject userMemberObject = userMembersArray.getJSONObject(i);
                 JSONObject userObject = userMemberObject.getJSONObject("user");
-                group.getUserMembers().add(UserReader.parseUser(userObject));
+                group.getUserMembers().add(JsonUserReader.parseUser(userObject));
             }
         }
 
@@ -269,7 +269,7 @@ public class GroupReader
             {
                 JSONObject userAdminObject = userAdminsArray.getJSONObject(i);
                 JSONObject userObject = userAdminObject.getJSONObject("user");
-                group.getUserAdmins().add(UserReader.parseUser(userObject));
+                group.getUserAdmins().add(JsonUserReader.parseUser(userObject));
             }
         }
 
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/GroupWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java
similarity index 96%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/GroupWriter.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java
index d5a1f1b684a75eb1f3fedd04286df23e95cac6e5..aa78fa68a379ac903cc63fe005bd66d3fecdf699 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/GroupWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonGroupWriter.java
@@ -88,7 +88,7 @@ import java.io.Writer;
 import java.security.Principal;
 import java.text.DateFormat;
 
-public class GroupWriter
+public class JsonGroupWriter
 {
     /**
      * Write a Group to a StringBuilder.
@@ -175,7 +175,7 @@ public class GroupWriter
         // Group owner
         if (group.getOwner() != null)
         {
-            groupObject.put("owner", UserWriter.getUserObject(group.getOwner()));
+            groupObject.put("owner", JsonUserWriter.getUserObject(group.getOwner()));
         }
 
         if (deepCopy)
@@ -200,7 +200,7 @@ public class GroupWriter
                 for (GroupProperty property : group.getProperties())
                 {
                     JSONObject propertyObject = new JSONObject();
-                    propertyObject.put("property", GroupPropertyWriter.write(property));
+                    propertyObject.put("property", JsonGroupPropertyWriter.write(property));
                     propertiesArray.put(propertyObject);
                 }
                 groupObject.put("properties", propertiesArray);
@@ -223,7 +223,7 @@ public class GroupWriter
                 JSONArray userMembersArray = new JSONArray();
                 for (User<? extends Principal> userMember : group.getUserMembers())
                 {
-                    userMembersArray.put(UserWriter.getUserObject(userMember));
+                    userMembersArray.put(JsonUserWriter.getUserObject(userMember));
                 }
                 groupObject.put("userMembers", userMembersArray);
             }
@@ -245,7 +245,7 @@ public class GroupWriter
                 JSONArray userAdminsArray = new JSONArray();
                 for (User<? extends Principal> userAdmin : group.getUserAdmins())
                 {
-                    userAdminsArray.put(UserWriter.getUserObject(userAdmin));
+                    userAdminsArray.put(JsonUserWriter.getUserObject(userAdmin));
                 }
                 groupObject.put("userAdmins", userAdminsArray);
             }
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java
similarity index 99%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java
index 308148bcdadde1530c994bc1bea70a7a61f9cd14..5bf9317a44b6c30c61b50f569471f652dc875daa 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserListWriter.java
@@ -80,7 +80,7 @@ import java.util.Map;
 /**
  * Class to write out, as JSON, a list of user entries.
  */
-public class UsersWriter
+public class JsonUserListWriter
 {
     public static void write(final Map<String, PersonalDetails> users,
                              final Writer writer) throws IOException
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java
similarity index 96%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserReader.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java
index b6aedd7f92293b5f7c49580ff44fd5ef20078567..f2d9db38d3c5459c8d86b0cf2f7c9d9f870d5230 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserReader.java
@@ -81,7 +81,7 @@ import java.io.Reader;
 import java.security.Principal;
 import java.util.Scanner;
 
-public class UserReader
+public class JsonUserReader
 {
     /**
      * Construct a User from a InputStream.
@@ -162,7 +162,7 @@ public class UserReader
         JSONObject userIDObject = userObject.getJSONObject("userID");
         JSONObject userIDIdentityObject = userIDObject.getJSONObject("identity");
 
-        Principal userID = IdentityReader.read(userIDIdentityObject);
+        Principal userID = JsonIdentityReader.read(userIDIdentityObject);
         User<Principal> user = new User<Principal>(userID);
 
         // identities
@@ -173,7 +173,7 @@ public class UserReader
             {
                 JSONObject identitiesObject = identitiesArray.getJSONObject(i);
                 JSONObject identityObject = identitiesObject.getJSONObject(("identity"));
-                user.getIdentities().add(IdentityReader.read(identityObject));
+                user.getIdentities().add(JsonIdentityReader.read(identityObject));
             }
         }
 
@@ -185,7 +185,7 @@ public class UserReader
             {
                 JSONObject detailsObject = detailsArray.getJSONObject(i);
                 JSONObject userDetailsObject = detailsObject.getJSONObject(UserDetails.NAME);
-                user.details.add(UserDetailsReader.read(userDetailsObject));
+                user.details.add(JsonUserDetailsReader.read(userDetailsObject));
             }
         }
 
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserRequestReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java
similarity index 97%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserRequestReader.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java
index 4f246e9df6e9d07618244a51eb960b8192d8a3f2..2a5c8d394e39520237c503d6937a50445be0b460 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserRequestReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserRequestReader.java
@@ -78,7 +78,7 @@ import java.io.*;
 import java.security.Principal;
 import java.util.Scanner;
 
-public class UserRequestReader
+public class JsonUserRequestReader
 {
     /**
      * Construct a UserRequest from an JSON String source.
@@ -159,10 +159,10 @@ public class UserRequestReader
         throws ReaderException, JSONException
     {
         final User<Principal> user =
-                ca.nrc.cadc.ac.json.UserReader.parseUser(
-                        userRequestObject.getJSONObject("user"));
+                JsonUserReader.parseUser(
+                    userRequestObject.getJSONObject("user"));
 
         return new UserRequest<Principal>(user, userRequestObject.
-                getString("password"));
+                getString("password").toCharArray());
     }
 }
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java
similarity index 96%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserWriter.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java
index 2865235807f885d24cbe3986b370c50e5bf8d753..41da645e0ad3cac0a85bcfcde103520644bc5fd4 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UserWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/JsonUserWriter.java
@@ -85,7 +85,7 @@ import java.io.Writer;
 import java.security.Principal;
 import java.util.Set;
 
-public class UserWriter
+public class JsonUserWriter
 {
     /**
      * Write a User as a JSON string to a StringBuilder.
@@ -164,7 +164,7 @@ public class UserWriter
     {
         JSONObject userObject = new JSONObject();
         JSONObject userIDIdentityObject = new JSONObject();
-        userIDIdentityObject.put("identity", IdentityWriter.write(user.getUserID()));
+        userIDIdentityObject.put("identity", JsonIdentityWriter.write(user.getUserID()));
         userObject.put("userID", userIDIdentityObject);
 
         // identities
@@ -175,7 +175,7 @@ public class UserWriter
             for (Principal identity : identities)
             {
                 JSONObject identityObject = new JSONObject();
-                identityObject.put("identity" , IdentityWriter.write(identity));
+                identityObject.put("identity" , JsonIdentityWriter.write(identity));
                 identityArray.put(identityObject);
             }
             userObject.put("identities", identityArray);
@@ -189,7 +189,7 @@ public class UserWriter
             for (UserDetails userDetail : userDetails)
             {
                 JSONObject detailsObject = new JSONObject();
-                detailsObject.put(UserDetails.NAME , UserDetailsWriter.write(userDetail));
+                detailsObject.put(UserDetails.NAME , JsonUserDetailsWriter.write(userDetail));
                 detailsArray.put(detailsObject);
             }
             userObject.put("details", detailsArray);
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupsReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java
similarity index 95%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupsReader.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java
index c0c31fbe4a2ecfbbb7f44e0baf411cf15f08745c..cd962918e443f8d3db33cd7eead08d475285543d 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupsReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java
@@ -84,7 +84,11 @@ import org.jdom2.Document;
 import org.jdom2.Element;
 import org.jdom2.JDOMException;
 
-public class GroupsReader
+/**
+ * Class to read an XML representation of a list of Groups
+ * into a List of Group objects.
+ */
+public class GroupListReader
 {
     /**
      * Construct a list of Group's from an XML String source.
@@ -95,7 +99,7 @@ public class GroupsReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static List<Group> read(String xml)
+    public List<Group> read(String xml)
         throws ReaderException, IOException, URISyntaxException
     {
         if (xml == null)
@@ -114,7 +118,7 @@ public class GroupsReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static List<Group> read(InputStream in)
+    public List<Group> read(InputStream in)
         throws ReaderException, IOException, URISyntaxException
     {
         if (in == null)
@@ -142,7 +146,7 @@ public class GroupsReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static List<Group> read(Reader reader)
+    public List<Group> read(Reader reader)
         throws ReaderException, IOException, URISyntaxException
     {
         if (reader == null)
@@ -182,7 +186,7 @@ public class GroupsReader
         List<Element> groupElements = groupsElement.getChildren("group");
         for (Element groupElement : groupElements)
         {
-            groups.add(ca.nrc.cadc.ac.xml.GroupReader.parseGroup(groupElement));
+            groups.add(GroupReader.parseGroup(groupElement));
         }
 
         return groups;
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupsWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java
similarity index 90%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupsWriter.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java
index fb92d2cd268c54985b379954a90493888043de8e..b3707fb3d7ce6bb3e2f3c16a6e9f59c01606b786 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupsWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java
@@ -15,7 +15,10 @@ import org.jdom2.Element;
 import org.jdom2.output.Format;
 import org.jdom2.output.XMLOutputter;
 
-public class GroupsWriter
+/**
+ * Class to write a XML representation from a Collection of Groups objects.
+ */
+public class GroupListWriter
 {
     /**
      * Write a List of Group's to a StringBuilder.
@@ -24,7 +27,7 @@ public class GroupsWriter
      * @throws java.io.IOException
      * @throws WriterException
      */
-    public static void write(Collection<Group> groups, StringBuilder builder)
+    public void write(Collection<Group> groups, StringBuilder builder)
         throws IOException, WriterException
     {
         write(groups, new StringBuilderWriter(builder));
@@ -38,7 +41,7 @@ public class GroupsWriter
      * @throws IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(Collection<Group> groups, OutputStream out)
+    public void write(Collection<Group> groups, OutputStream out)
         throws IOException, WriterException
     {
         OutputStreamWriter outWriter;
@@ -61,7 +64,7 @@ public class GroupsWriter
      * @throws IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(Collection<Group> groups, Writer writer)
+    public void write(Collection<Group> groups, Writer writer)
         throws IOException, WriterException
     {
         if (groups == null)
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java
index 8cfc37eec446e677bb9f648cfe4a52d2dc82f2b9..8a66c7e95aef3e98abffdb2906bb0bf369a9f4a6 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java
@@ -90,6 +90,9 @@ import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.List;
 
+/**
+ * Class to read a XML representation of a Group to a Group object.
+ */
 public class GroupReader
 {
 
@@ -102,7 +105,7 @@ public class GroupReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static Group read(String xml)
+    public Group read(String xml)
         throws ReaderException, IOException, URISyntaxException
     {
         if (xml == null)
@@ -121,7 +124,7 @@ public class GroupReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static Group read(InputStream in)
+    public Group read(InputStream in)
         throws ReaderException, IOException
     {
         if (in == null)
@@ -149,7 +152,7 @@ public class GroupReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static Group read(Reader reader)
+    public Group read(Reader reader)
         throws ReaderException, IOException
     {
         if (reader == null)
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java
index 18f307a80afea5fb5552e34f2b9c9b338e871c1b..380ba79a8d7ec2fa8e203f8e7f6d8bafbb51ff0e 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java
@@ -90,6 +90,9 @@ import java.io.Writer;
 import java.security.Principal;
 import java.text.DateFormat;
 
+/**
+ * Class to write a XML representation of a Group object.
+ */
 public class GroupWriter
 {
     /**
@@ -99,7 +102,7 @@ public class GroupWriter
      * @throws java.io.IOException
      * @throws WriterException
      */
-    public static void write(Group group, StringBuilder builder)
+    public void write(Group group, StringBuilder builder)
         throws IOException, WriterException
     {
         write(group, new StringBuilderWriter(builder));
@@ -113,7 +116,7 @@ public class GroupWriter
      * @throws IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(Group group, OutputStream out)
+    public void write(Group group, OutputStream out)
         throws IOException, WriterException
     {
         OutputStreamWriter outWriter;
@@ -136,7 +139,7 @@ public class GroupWriter
      * @throws IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(Group group, Writer writer)
+    public void write(Group group, Writer writer)
         throws IOException, WriterException
     {
         if (group == null)
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java
similarity index 96%
rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java
rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java
index 757af4901c0a2572ac563350ca76e142dd7d12ea..f08d4de4c4ba371da692b858c25e51198cb6abe0 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java
@@ -78,7 +78,10 @@ import java.io.IOException;
 import java.io.Writer;
 import java.util.Map;
 
-public class UsersWriter
+/**
+ * Class to write a XML representation of a Collection of User's.
+ */
+public class UserListWriter
 {
     /**
      * Write the Map of User entries as XML.
@@ -87,8 +90,8 @@ public class UsersWriter
      * @param writer            The Writer to output to.
      * @throws IOException      Any writing errors.
      */
-    public static void write(final Map<String, PersonalDetails> users,
-                             final Writer writer) throws IOException
+    public void write(final Map<String, PersonalDetails> users,
+                      final Writer writer) throws IOException
     {
         // Create the root users Element.
         final Element usersElement = new Element("users");
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java
index e9b957c29ed85fcc8133c781a2b8618e15650116..7cceba392b1852cedacbe10a1f25bd04a06492bf 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java
@@ -85,6 +85,9 @@ import java.net.URISyntaxException;
 import java.security.Principal;
 import java.util.List;
 
+/**
+ * Class to read a XML representation of a User to a User object.
+ */
 public class UserReader
 {
     /**
@@ -96,7 +99,7 @@ public class UserReader
      * @throws java.io.IOException
      * @throws java.net.URISyntaxException
      */
-    public static User<Principal> read(String xml)
+    public User<Principal> read(String xml)
         throws IOException, URISyntaxException
     {
         if (xml == null)
@@ -113,7 +116,7 @@ public class UserReader
      * @return User User.
      * @throws java.io.IOException
      */
-    public static User<Principal> read(InputStream in)
+    public User<Principal> read(InputStream in)
         throws IOException
     {
         if (in == null)
@@ -140,7 +143,7 @@ public class UserReader
      * @throws ReaderException
      * @throws java.io.IOException
      */
-    public static User<Principal> read(Reader reader)
+    public User<Principal> read(Reader reader)
         throws IOException
     {
         if (reader == null)
@@ -185,7 +188,8 @@ public class UserReader
             throw new ReaderException(error);
         }
 
-        Principal userID = IdentityReader.read(userIDIdentityElement);
+        IdentityReader identityReader = new IdentityReader();
+        Principal userID = identityReader.read(userIDIdentityElement);
 
         User<Principal> user = new User<Principal>(userID);
 
@@ -196,7 +200,7 @@ public class UserReader
             List<Element> identityElements = identitiesElement.getChildren("identity");
             for (Element identityElement : identityElements)
             {
-                user.getIdentities().add(IdentityReader.read(identityElement));
+                user.getIdentities().add(identityReader.read(identityElement));
             }
 
         }
@@ -205,10 +209,11 @@ public class UserReader
         Element detailsElement = userElement.getChild("details");
         if (detailsElement != null)
         {
+            UserDetailsReader userDetailsReader = new UserDetailsReader();
             List<Element> userDetailsElements = detailsElement.getChildren("userDetails");
             for (Element userDetailsElement : userDetailsElements)
             {
-                user.details.add(UserDetailsReader.read(userDetailsElement));
+                user.details.add(userDetailsReader.read(userDetailsElement));
             }
         }
 
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java
index da30cafda3aa6e952fa5eec3682318f9543b5555..e44eba1e4dc37fe8f9fa81b0f7b9629bf271e65e 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java
@@ -84,6 +84,9 @@ import org.jdom2.Document;
 import org.jdom2.Element;
 import org.jdom2.JDOMException;
 
+/**
+ * Class to read a XML representation of a UserRequest to a UserRequest object.
+ */
 public class UserRequestReader
 {
     /**
@@ -93,7 +96,7 @@ public class UserRequestReader
      * @return UserRequest UserRequest.
      * @throws java.io.IOException
      */
-    public static UserRequest<Principal> read(String xml)
+    public UserRequest<Principal> read(String xml)
         throws IOException
     {
         if (xml == null)
@@ -111,7 +114,7 @@ public class UserRequestReader
      * @throws ReaderException
      * @throws java.io.IOException
      */
-    public static UserRequest<Principal> read(InputStream in)
+    public UserRequest<Principal> read(InputStream in)
         throws IOException
     {
         if (in == null)
@@ -138,7 +141,7 @@ public class UserRequestReader
      * @throws ReaderException
      * @throws java.io.IOException
      */
-    public static UserRequest<Principal> read(Reader reader)
+    public UserRequest<Principal> read(Reader reader)
         throws IOException
     {
         if (reader == null)
@@ -186,6 +189,6 @@ public class UserRequestReader
         }
         String password = passwordElement.getText();
 
-        return new UserRequest<Principal>(user, password);
+        return new UserRequest<Principal>(user, password.toCharArray());
     }
 }
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java
index 10aaf852a0fd05e5add47518984e50ce132856cc..fe0ffee96a6fbbd1a9e9a70f77d575dfbdf0a629 100644
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java
@@ -81,6 +81,9 @@ import java.io.IOException;
 import java.io.Writer;
 import java.security.Principal;
 
+/**
+ * Class to write a XML representation of a UserRequest object.
+ */
 public class UserRequestWriter
 {
     /**
@@ -91,7 +94,7 @@ public class UserRequestWriter
      * @throws java.io.IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(UserRequest<? extends Principal> userRequest, StringBuilder builder)
+    public void write(UserRequest<? extends Principal> userRequest, StringBuilder builder)
         throws IOException, WriterException
     {
         write(userRequest, new StringBuilderWriter(builder));
@@ -135,7 +138,7 @@ public class UserRequestWriter
 
         // password element
         Element passwordElement = new Element("password");
-        passwordElement.setText(userRequest.getPassword());
+        passwordElement.setText(String.valueOf(userRequest.getPassword()));
         userRequestElement.addContent(passwordElement);
 
         return userRequestElement;
diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java
index b1d6642de691ebc47e3516054b08bdb0a640976a..86327ad8f27e7e77bfaa4b17291fe4d8830e2fbf 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java
@@ -86,6 +86,9 @@ import java.io.Writer;
 import java.security.Principal;
 import java.util.Set;
 
+/**
+ * Class to write a XML representation of a User object.
+ */
 public class UserWriter
 {
     /**
@@ -96,7 +99,7 @@ public class UserWriter
      * @throws java.io.IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(User<? extends Principal> user, StringBuilder builder)
+    public void write(User<? extends Principal> user, StringBuilder builder)
         throws IOException, WriterException
     {
         write(user, new StringBuilderWriter(builder));
@@ -110,7 +113,7 @@ public class UserWriter
      * @throws IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(User<? extends Principal> user, OutputStream out)
+    public void write(User<? extends Principal> user, OutputStream out)
         throws IOException, WriterException
     {                
         OutputStreamWriter outWriter;
@@ -133,7 +136,7 @@ public class UserWriter
      * @throws IOException if the writer fails to write.
      * @throws WriterException
      */
-    public static void write(User<? extends Principal> user, Writer writer)
+    public void write(User<? extends Principal> user, Writer writer)
         throws IOException, WriterException
     {
         if (user == null)
@@ -158,8 +161,9 @@ public class UserWriter
         Element userElement = new Element("user");
 
         // userID element
+        IdentityWriter identityWriter = new IdentityWriter();
         Element userIDElement = new Element("userID");
-        userIDElement.addContent(IdentityWriter.write(user.getUserID()));
+        userIDElement.addContent(identityWriter.write(user.getUserID()));
         userElement.addContent(userIDElement);
 
         // identities
@@ -169,7 +173,7 @@ public class UserWriter
             Element identitiesElement = new Element("identities");
             for (Principal identity : identities)
             {
-                identitiesElement.addContent(IdentityWriter.write(identity));
+                identitiesElement.addContent(identityWriter.write(identity));
             }
             userElement.addContent(identitiesElement);
         }
@@ -177,11 +181,12 @@ public class UserWriter
         // details
         if (!user.details.isEmpty())
         {
+            UserDetailsWriter userDetailsWriter = new UserDetailsWriter();
             Element detailsElement = new Element("details");
             Set<UserDetails> userDetails = user.details;
             for (UserDetails userDetail : userDetails)
             {
-                detailsElement.addContent(UserDetailsWriter.write(userDetail));
+                detailsElement.addContent(userDetailsWriter.write(userDetail));
             }
             userElement.addContent(detailsElement);
         }
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserRequestTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserRequestTest.java
index 9507d25e5b83156d2627652c90560565c4d30ee3..7bc85ed92c3c65e1ddd07c0b4c543ea4e6790a02 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserRequestTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/UserRequestTest.java
@@ -83,7 +83,9 @@ public class UserRequestTest
     @Test
     public void simpleEqualityTests() throws Exception
     {
-        UserRequest<HttpPrincipal> ur1 = new UserRequest<HttpPrincipal>(new User(new HttpPrincipal(("foo"))), "password");
+        UserRequest<HttpPrincipal> ur1 =
+            new UserRequest<HttpPrincipal>(
+                new User<HttpPrincipal>(new HttpPrincipal(("foo"))), "password".toCharArray());
         UserRequest<HttpPrincipal> ur2 = ur1;
         assertEquals(ur1, ur2);
         assertEquals(ur1.getUser(), ur2.getUser());
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapperTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapperTest.java
index fe977e4e3e5120c17b8e407df7bc210767384099..d8bd34ea6a1aae47bc8b0bd4b7182f3838932329 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapperTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapperTest.java
@@ -80,15 +80,15 @@ import org.junit.Test;
 import static org.junit.Assert.*;
 
 
-public class JSONUserListInputStreamWrapperTest
+public class JsonUserListInputStreamWrapperTest
 {
     @Test
     public void readInputStream() throws Exception
     {
         final List<User<HttpPrincipal>> output =
                 new ArrayList<User<HttpPrincipal>>();
-        final JSONUserListInputStreamWrapper testSubject =
-                new JSONUserListInputStreamWrapper(output);
+        final JsonUserListInputStreamWrapper testSubject =
+                new JsonUserListInputStreamWrapper(output);
         final InputStream inputStream =
                 new ByteArrayInputStream("[{\"id\":\"CADCTest\",\"firstName\":\"CADCtest\",\"lastName\":\"USER\"}\n,{\"id\":\"User_2\",\"firstName\":\"User\",\"lastName\":\"2\"}]".getBytes());
 
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/GroupReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonGroupReaderWriterTest.java
similarity index 93%
rename from projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/GroupReaderWriterTest.java
rename to projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonGroupReaderWriterTest.java
index b60eee86191be9b62deda3174b51b9a1fe55a5e3..970c112d64728cf4055c17255cd072aaccd79794 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/GroupReaderWriterTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonGroupReaderWriterTest.java
@@ -93,9 +93,9 @@ import static org.junit.Assert.fail;
  *
  * @author jburke
  */
-public class GroupReaderWriterTest
+public class JsonGroupReaderWriterTest
 {
-    private static Logger log = Logger.getLogger(GroupReaderWriterTest.class);
+    private static Logger log = Logger.getLogger(JsonGroupReaderWriterTest.class);
 
     @Test
     public void testReaderExceptions()
@@ -104,7 +104,7 @@ public class GroupReaderWriterTest
         try
         {
             String s = null;
-            Group g = GroupReader.read(s);
+            Group g = JsonGroupReader.read(s);
             fail("null String should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -112,7 +112,7 @@ public class GroupReaderWriterTest
         try
         {
             InputStream in = null;
-            Group g = GroupReader.read(in);
+            Group g = JsonGroupReader.read(in);
             fail("null InputStream should throw IOException");
         }
         catch (IOException e) {}
@@ -120,7 +120,7 @@ public class GroupReaderWriterTest
         try
         {
             Reader r = null;
-            Group g = GroupReader.read(r);
+            Group g = JsonGroupReader.read(r);
             fail("null element should throw ReaderException");
         }
         catch (IllegalArgumentException e) {}
@@ -132,7 +132,7 @@ public class GroupReaderWriterTest
     {
         try
         {
-            GroupWriter.write(null, new StringBuilder());
+            JsonGroupWriter.write(null, new StringBuilder());
             fail("null Group should throw WriterException");
         }
         catch (WriterException e) {}
@@ -145,10 +145,10 @@ public class GroupReaderWriterTest
         Group expected = new Group("groupID", null);
                 
         StringBuilder json = new StringBuilder();
-        GroupWriter.write(expected, json);
+        JsonGroupWriter.write(expected, json);
         assertFalse(json.toString().isEmpty());
         
-        Group actual = GroupReader.read(json.toString());
+        Group actual = JsonGroupReader.read(json.toString());
         assertNotNull(actual);
         assertEquals(expected, actual);
     }
@@ -173,10 +173,10 @@ public class GroupReaderWriterTest
         expected.getUserAdmins().add(userAdmin);
         
         StringBuilder json = new StringBuilder();
-        GroupWriter.write(expected, json);
+        JsonGroupWriter.write(expected, json);
         assertFalse(json.toString().isEmpty());
 
-        Group actual = GroupReader.read(json.toString());
+        Group actual = JsonGroupReader.read(json.toString());
         assertNotNull(actual);
         assertEquals(expected, actual);
         assertEquals(expected.description, actual.description);
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/UserReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java
similarity index 92%
rename from projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/UserReaderWriterTest.java
rename to projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java
index 6e468da861196bcd48c20c419b02ffa21bb0c684..bc3a7c0fb491f9edf84341a921800ec19cd2106d 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/UserReaderWriterTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserReaderWriterTest.java
@@ -91,9 +91,9 @@ import static org.junit.Assert.fail;
  *
  * @author jburke
  */
-public class UserReaderWriterTest
+public class JsonUserReaderWriterTest
 {
-    private static Logger log = Logger.getLogger(UserReaderWriterTest.class);
+    private static Logger log = Logger.getLogger(JsonUserReaderWriterTest.class);
 
     @Test
     public void testReaderExceptions()
@@ -102,7 +102,7 @@ public class UserReaderWriterTest
         try
         {
             String s = null;
-            User<? extends Principal> u = UserReader.read(s);
+            User<? extends Principal> u = JsonUserReader.read(s);
             fail("null String should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -110,7 +110,7 @@ public class UserReaderWriterTest
         try
         {
             InputStream in = null;
-            User<? extends Principal> u = UserReader.read(in);
+            User<? extends Principal> u = JsonUserReader.read(in);
             fail("null InputStream should throw IOException");
         }
         catch (IOException e) {}
@@ -118,7 +118,7 @@ public class UserReaderWriterTest
         try
         {
             Reader r = null;
-            User<? extends Principal> u = UserReader.read(r);
+            User<? extends Principal> u = JsonUserReader.read(r);
             fail("null Reader should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -130,7 +130,7 @@ public class UserReaderWriterTest
     {
         try
         {
-            UserWriter.write(null, new StringBuilder());
+            JsonUserWriter.write(null, new StringBuilder());
             fail("null User should throw WriterException");
         }
         catch (WriterException e) {}
@@ -146,10 +146,10 @@ public class UserReaderWriterTest
         expected.details.add(new PosixDetails(123l, 456l, "foo"));
 
         StringBuilder json = new StringBuilder();
-        UserWriter.write(expected, json);
+        JsonUserWriter.write(expected, json);
         assertFalse(json.toString().isEmpty());
         
-        User<? extends Principal> actual = UserReader.read(json.toString());
+        User<? extends Principal> actual = JsonUserReader.read(json.toString());
         assertNotNull(actual);
         assertEquals(expected, actual);
     }
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupReaderWriterTest.java
index 12f3f5093d5f35c4b98aa0d6bcdaea8b31125477..3c3dbe07116b1f1e3f2e41bfc49b39a12d2edb94 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupReaderWriterTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupReaderWriterTest.java
@@ -104,7 +104,8 @@ public class GroupReaderWriterTest
         try
         {
             String s = null;
-            Group g = GroupReader.read(s);
+            GroupReader groupReader = new GroupReader();
+            Group g = groupReader.read(s);
             fail("null String should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -112,7 +113,8 @@ public class GroupReaderWriterTest
         try
         {
             InputStream in = null;
-            Group g = GroupReader.read(in);
+            GroupReader groupReader = new GroupReader();
+            Group g = groupReader.read(in);
             fail("null InputStream should throw IOException");
         }
         catch (IOException e) {}
@@ -120,7 +122,8 @@ public class GroupReaderWriterTest
         try
         {
             Reader r = null;
-            Group g = GroupReader.read(r);
+            GroupReader groupReader = new GroupReader();
+            Group g = groupReader.read(r);
             fail("null element should throw ReaderException");
         }
         catch (IllegalArgumentException e) {}
@@ -132,7 +135,8 @@ public class GroupReaderWriterTest
     {
         try
         {
-            GroupWriter.write(null, new StringBuilder());
+            GroupWriter groupWriter = new GroupWriter();
+            groupWriter.write(null, new StringBuilder());
             fail("null Group should throw WriterException");
         }
         catch (WriterException e) {}
@@ -145,10 +149,12 @@ public class GroupReaderWriterTest
         Group expected = new Group("groupID", null);
                 
         StringBuilder xml = new StringBuilder();
-        GroupWriter.write(expected, xml);
+        GroupWriter groupWriter = new GroupWriter();
+        groupWriter.write(expected, xml);
         assertFalse(xml.toString().isEmpty());
-        
-        Group actual = GroupReader.read(xml.toString());
+
+        GroupReader groupReader = new GroupReader();
+        Group actual = groupReader.read(xml.toString());
         assertNotNull(actual);
         assertEquals(expected, actual);
     }
@@ -173,10 +179,12 @@ public class GroupReaderWriterTest
         expected.getUserAdmins().add(userAdmin);
         
         StringBuilder xml = new StringBuilder();
-        GroupWriter.write(expected, xml);
+        GroupWriter groupWriter = new GroupWriter();
+        groupWriter.write(expected, xml);
         assertFalse(xml.toString().isEmpty());
-        
-        Group actual = GroupReader.read(xml.toString());
+
+        GroupReader groupReader = new GroupReader();
+        Group actual = groupReader.read(xml.toString());
         assertNotNull(actual);
         assertEquals(expected, actual);
         assertEquals(expected.description, actual.description);
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java
index 1d4d9f3052d68324ad7db6e332215c985108c9aa..0281eaf87cf1456c0d5781fc187012d3d5c7caa2 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupsReaderWriterTest.java
@@ -99,7 +99,8 @@ public class GroupsReaderWriterTest
         try
         {
             String s = null;
-            List<Group> g = GroupsReader.read(s);
+            GroupListReader groupListReader = new GroupListReader();
+            List<Group> g = groupListReader.read(s);
             fail("null String should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -107,7 +108,8 @@ public class GroupsReaderWriterTest
         try
         {
             InputStream in = null;
-            List<Group> g = GroupsReader.read(in);
+            GroupListReader groupListReader = new GroupListReader();
+            List<Group> g = groupListReader.read(in);
             fail("null InputStream should throw IOException");
         }
         catch (IOException e) {}
@@ -115,7 +117,8 @@ public class GroupsReaderWriterTest
         try
         {
             Reader r = null;
-            List<Group> g = GroupsReader.read(r);
+            GroupListReader groupListReader = new GroupListReader();
+            List<Group> g = groupListReader.read(r);
             fail("null element should throw ReaderException");
         }
         catch (IllegalArgumentException e) {}
@@ -127,7 +130,8 @@ public class GroupsReaderWriterTest
     {
         try
         {
-            GroupsWriter.write(null, new StringBuilder());
+            GroupListWriter groupListWriter = new GroupListWriter();
+            groupListWriter.write(null, new StringBuilder());
             fail("null Group should throw WriterException");
         }
         catch (WriterException e) {}
@@ -142,10 +146,12 @@ public class GroupsReaderWriterTest
         expected.add(new Group("group2", null));
         
         StringBuilder xml = new StringBuilder();
-        GroupsWriter.write(expected, xml);
+        GroupListWriter groupListWriter = new GroupListWriter();
+        groupListWriter.write(expected, xml);
         assertFalse(xml.toString().isEmpty());
-        
-        List<Group> actual = GroupsReader.read(xml.toString());
+
+        GroupListReader groupListReader = new GroupListReader();
+        List<Group> actual = groupListReader.read(xml.toString());
         assertNotNull(actual);
         assertEquals(expected.size(), actual.size());
         assertEquals(expected.get(0), actual.get(0));
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java
index a0e3d54881d83f310dbc616884dcf37277066cd6..4e8d9f2b066ef053fb815854ee2a3ce03c66e30c 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserReaderWriterTest.java
@@ -101,7 +101,8 @@ public class UserReaderWriterTest
         try
         {
             String s = null;
-            User<? extends Principal> u = UserReader.read(s);
+            UserReader userReader = new UserReader();
+            User<? extends Principal> u = userReader.read(s);
             fail("null String should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -109,7 +110,8 @@ public class UserReaderWriterTest
         try
         {
             InputStream in = null;
-            User<? extends Principal> u = UserReader.read(in);
+            UserReader userReader = new UserReader();
+            User<? extends Principal> u = userReader.read(in);
             fail("null InputStream should throw IOException");
         }
         catch (IOException e) {}
@@ -117,7 +119,8 @@ public class UserReaderWriterTest
         try
         {
             Reader r = null;
-            User<? extends Principal> u = UserReader.read(r);
+            UserReader userReader = new UserReader();
+            User<? extends Principal> u = userReader.read(r);
             fail("null Reader should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -129,7 +132,8 @@ public class UserReaderWriterTest
     {
         try
         {
-            ca.nrc.cadc.ac.xml.UserWriter.write(null, new StringBuilder());
+            UserWriter userWriter = new UserWriter();
+            userWriter.write(null, new StringBuilder());
             fail("null User should throw WriterException");
         }
         catch (WriterException e) {}
@@ -144,10 +148,12 @@ public class UserReaderWriterTest
         expected.details.add(new PersonalDetails("firstname", "lastname"));
         
         StringBuilder xml = new StringBuilder();
-        UserWriter.write(expected, xml);
+        UserWriter userWriter = new UserWriter();
+        userWriter.write(expected, xml);
         assertFalse(xml.toString().isEmpty());
-        
-        User<? extends Principal> actual = UserReader.read(xml.toString());
+
+        UserReader userReader = new UserReader();
+        User<? extends Principal> actual = userReader.read(xml.toString());
         assertNotNull(actual);
         assertEquals(expected, actual);
     }
diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserRequestReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserRequestReaderWriterTest.java
index 191fb9b603131b691659c843aa11b25303309d14..30dec9315f46556d62e8193380f68452e29b4a88 100644
--- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserRequestReaderWriterTest.java
+++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserRequestReaderWriterTest.java
@@ -99,7 +99,8 @@ public class UserRequestReaderWriterTest
         try
         {
             String s = null;
-            UserRequest u = UserRequestReader.read(s);
+            UserRequestReader userRequestReader = new UserRequestReader();
+            UserRequest u = userRequestReader.read(s);
             fail("null String should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -107,7 +108,8 @@ public class UserRequestReaderWriterTest
         try
         {
             InputStream in = null;
-            UserRequest u = UserRequestReader.read(in);
+            UserRequestReader userRequestReader = new UserRequestReader();
+            UserRequest u = userRequestReader.read(in);
             fail("null InputStream should throw IOException");
         }
         catch (IOException e) {}
@@ -115,7 +117,8 @@ public class UserRequestReaderWriterTest
         try
         {
             Reader r = null;
-            UserRequest u = UserRequestReader.read(r);
+            UserRequestReader userRequestReader = new UserRequestReader();
+            UserRequest u = userRequestReader.read(r);
             fail("null Reader should throw IllegalArgumentException");
         }
         catch (IllegalArgumentException e) {}
@@ -127,7 +130,8 @@ public class UserRequestReaderWriterTest
     {
         try
         {
-            UserRequestWriter.write(null, new StringBuilder());
+            UserRequestWriter userRequestWriter = new UserRequestWriter();
+            userRequestWriter.write(null, new StringBuilder());
             fail("null UserRequest should throw WriterException");
         }
         catch (WriterException e) {}
@@ -137,22 +141,26 @@ public class UserRequestReaderWriterTest
     public void testReadWrite()
         throws Exception
     {
-        User<? extends Principal> expectedUser = new User<Principal>(new HttpPrincipal("foo"));
+        User<HttpPrincipal> expectedUser = new User<HttpPrincipal>(new HttpPrincipal("foo"));
         expectedUser.getIdentities().add(new NumericPrincipal(123l));
         expectedUser.details.add(new PersonalDetails("firstname", "lastname"));
 
-        String expectedPassword = "123456";
+        char[] expectedPassword = "123456".toCharArray();
 
-        UserRequest expected = new UserRequest(expectedUser, expectedPassword);
+        UserRequest<HttpPrincipal> expected =
+            new UserRequest<HttpPrincipal>(expectedUser, expectedPassword);
 
         StringBuilder xml = new StringBuilder();
-        UserRequestWriter.write(expected, xml);
+        UserRequestWriter userRequestWriter = new UserRequestWriter();
+        userRequestWriter.write(expected, xml);
         assertFalse(xml.toString().isEmpty());
-        
-        UserRequest actual = UserRequestReader.read(xml.toString());
+
+        UserRequestReader userRequestReader = new UserRequestReader();
+        UserRequest actual = userRequestReader.read(xml.toString());
         assertNotNull(actual);
         assertEquals(expected.getUser(), actual.getUser());
-        assertEquals(expected.getPassword(), actual.getPassword());
+        assertEquals(String.valueOf(expected.getPassword()),
+                     String.valueOf(actual.getPassword()));
     }
     
 }