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 70ee0595f868c4805fda36310ff6cbd9b9278a5b..6a7ec0cfa244665a668eb5573b8a3ca023e146b9 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
@@ -535,8 +535,16 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                         else if (memberDN.isDescendantOf(config.getGroupsDN(),
                                                          false))
                         {
-                            ldapGroup.getGroupMembers().add(new Group(
-                                memberDN.getRDNString().replace("cn=", "")));
+                            try
+                            {
+                                ldapGroup.getGroupMembers().
+                                    add(new Group(getGroupID(memberDN)));
+                            }
+                            catch(GroupNotFoundException e)
+                            {
+                                // ignore as we are not cleaning up
+                                // deleted groups from the group members
+                            }
                         }
                         else
                         {
@@ -603,7 +611,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             mods.add(new Modification(ModificationType.REPLACE, "description", group.description));
         }
 
-        List<String> newMembers = new ArrayList<String>();
+        
+        Set<String> newMembers = new HashSet<String>();
         for (User<?> member : group.getUserMembers())
         {
             DN memberDN = userPersist.getUserDN(member);
@@ -618,7 +627,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             DN grDN = getGroupDN(gr.getID());
             newMembers.add(grDN.toNormalizedString());
         }
-        List<String> newAdmins = new ArrayList<String>();
+        Set<String> newAdmins = new HashSet<String>();
         for (User<?> member : group.getUserAdmins())
         {
             DN memberDN = userPersist.getUserDN(member);
@@ -908,13 +917,14 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
     }
     
     /**
-     * Returns a group based on its LDAP DN. The returned group is bare
-     * (contains only group ID, description, modifytimestamp).
+     * Returns a group based on its LDAP DN. The returned group does not contain
+     * members or admins
      * 
      * @param groupDN
      * @return
      * @throws com.unboundid.ldap.sdk.LDAPException
-     * @throws ca.nrc.cadc.ac.GroupNotFoundException
+     * @throws ca.nrc.cadc.ac.GroupNotFoundException - if group does not exist,
+     * it's deleted or caller has no access to it.
      */
     protected Group getGroup(final DN groupDN)
         throws LDAPException, GroupNotFoundException, UserNotFoundException
@@ -956,6 +966,53 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         return group;
     }
 
+    /**
+     * Returns a group ID corresponding to a DN. Although the groupID can be
+     * deduced from the group DN, this method checks if the group exists and
+     * it's active and throws an exception if any of those conditions are not
+     * met.
+     * 
+     * @param groupDN
+     * @return
+     * @throws com.unboundid.ldap.sdk.LDAPException
+     * @throws ca.nrc.cadc.ac.GroupNotFoundException - Group not found or not
+     * active
+     */
+    protected String getGroupID(final DN groupDN)
+        throws LDAPException, GroupNotFoundException
+    {
+        Filter filter = Filter.createEqualityFilter("entrydn", 
+                                                    groupDN.toNormalizedString());
+        
+        SearchRequest searchRequest =  new SearchRequest(
+                    config.getGroupsDN(), SearchScope.SUB, filter, 
+                    "cn", "nsaccountlock");
+            
+        searchRequest.addControl(
+                    new ProxiedAuthorizationV2RequestControl("dn:" + 
+                            getSubjectDN().toNormalizedString()));
+            
+        SearchResultEntry searchResult = 
+                getConnection().searchForEntry(searchRequest);
+
+        if (searchResult == null)
+        {
+            String msg = "Group not found " + groupDN;
+            logger.debug(msg);
+            throw new GroupNotFoundException(groupDN.toNormalizedString());
+        }
+        
+        if (searchResult.getAttribute("nsaccountlock") != null)
+        {
+            // deleted group
+            String msg = "Group not found " + groupDN;
+            logger.debug(msg);
+            throw new GroupNotFoundException(groupDN.toNormalizedString());
+        }
+
+        return searchResult.getAttributeValue("cn");
+    }
+    
     /**
      * 
      * @param groupID
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddGroupMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddGroupMemberAction.java
index 9577061cca259dcc76f5e4dae527685aafc7164d..c842e9708c09ea603ebc77c21173802586bd1bea 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddGroupMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddGroupMemberAction.java
@@ -73,7 +73,6 @@ import ca.nrc.cadc.ac.GroupAlreadyExistsException;
 import ca.nrc.cadc.ac.server.GroupPersistence;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 public class AddGroupMemberAction extends GroupsAction
 {
@@ -93,7 +92,7 @@ public class AddGroupMemberAction extends GroupsAction
     {
         GroupPersistence groupPersistence = getGroupPersistence();
         Group group = groupPersistence.getGroup(this.groupName);
-        Group toAdd = groupPersistence.getGroup(this.groupMemberName);
+        Group toAdd = new Group(this.groupMemberName);
         if (!group.getGroupMembers().add(toAdd))
         {
             throw new GroupAlreadyExistsException(this.groupMemberName);
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddUserMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddUserMemberAction.java
index d8a84b2650cf2b3d4cd191b5fbf7f4a54014235c..7c6873401e1aa28c94b36e0980ec70bedf72bea5 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddUserMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/AddUserMemberAction.java
@@ -99,14 +99,14 @@ public class AddUserMemberAction extends GroupsAction
         throws Exception
     {
         GroupPersistence groupPersistence = getGroupPersistence();
-        UserPersistence userPersistence = getUserPersistence();
         Group group = groupPersistence.getGroup(this.groupName);
         Principal userPrincipal = AuthenticationUtil.createPrincipal(this.userID, this.userIDType);
-        User toAdd = userPersistence.getUser(userPrincipal);
+        User<Principal> toAdd = new User(userPrincipal);
         if (!group.getUserMembers().add(toAdd))
         {
             throw new MemberAlreadyExistsException();
         }
+        
         groupPersistence.modifyGroup(group);
 
         List<String> addedMembers = new ArrayList<String>();
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsAction.java
index 02f64926a9982e7ae88b89bed6c054087cb473a9..42c0ac3cf8138d192991ae40b80da515016fd1dc 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsAction.java
@@ -132,56 +132,56 @@ public abstract class GroupsAction
         }
         catch (AccessControlException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = "Permission Denied";
             this.logInfo.setMessage(message);
             sendError(403, message);
         }
         catch (IllegalArgumentException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = e.getMessage();
             this.logInfo.setMessage(message);
             sendError(400, message);
         }
         catch (MemberNotFoundException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = "Member not found: " + e.getMessage();
             this.logInfo.setMessage(message);
             sendError(404, message);
         }
         catch (GroupNotFoundException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = "Group not found: " + e.getMessage();
             this.logInfo.setMessage(message);
             sendError(404, message);
         }
         catch (UserNotFoundException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = "User not found: " + e.getMessage();
             this.logInfo.setMessage(message);
             sendError(404, message);
         }
         catch (MemberAlreadyExistsException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = "Member already exists: " + e.getMessage();
             this.logInfo.setMessage(message);
             sendError(409, message);
         }
         catch (GroupAlreadyExistsException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             String message = "Group already exists: " + e.getMessage();
             this.logInfo.setMessage(message);
             sendError(409, message);
         }
         catch (UnsupportedOperationException e)
         {
-            log.debug(e);
+            log.debug(e.getMessage(), e);
             this.logInfo.setMessage("Not yet implemented.");
             sendError(501);
         }
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveGroupMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveGroupMemberAction.java
index 39e148916a204e9369340fe50a5b0eabc22c69bf..269984b17e2d626ed58551a7c5ad130349405cc4 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveGroupMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveGroupMemberAction.java
@@ -92,7 +92,7 @@ public class RemoveGroupMemberAction extends GroupsAction
     {
         GroupPersistence groupPersistence = getGroupPersistence();
         Group group = groupPersistence.getGroup(this.groupName);
-        Group toRemove = groupPersistence.getGroup(this.groupMemberName);
+        Group toRemove = new Group(this.groupMemberName);
         if (!group.getGroupMembers().remove(toRemove))
         {
             throw new GroupNotFoundException(this.groupMemberName);
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveUserMemberAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveUserMemberAction.java
index c9612f663c5009d88c9d00d17fa82974a266a6bb..9b4d34f73c8af063650ac3ecf5245ba2c7058b5b 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveUserMemberAction.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/RemoveUserMemberAction.java
@@ -97,10 +97,9 @@ public class RemoveUserMemberAction extends GroupsAction
         throws Exception
     {
         GroupPersistence groupPersistence = getGroupPersistence();
-        UserPersistence userPersistence = getUserPersistence();
         Group group = groupPersistence.getGroup(this.groupName);
         Principal userPrincipal = AuthenticationUtil.createPrincipal(this.userID, this.userIDType);
-        User toRemove = userPersistence.getUser(userPrincipal);
+        User<Principal> toRemove = new User(userPrincipal);
         if (!group.getUserMembers().remove(toRemove))
         {
             throw new MemberNotFoundException();
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java
index 7af54bc0ae0a9ec3c1e3621a31038538440a7ae9..bad3d32ac6ec804357f8bae67f88707fdca8d619 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java
@@ -68,6 +68,7 @@
 package ca.nrc.cadc.ac.server.ldap;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -90,17 +91,20 @@ import ca.nrc.cadc.ac.GroupNotFoundException;
 import ca.nrc.cadc.ac.GroupProperty;
 import ca.nrc.cadc.ac.Role;
 import ca.nrc.cadc.ac.User;
-import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.util.Log4jInit;
-import static org.junit.Assert.assertNotNull;
+import ca.nrc.cadc.auth.HttpPrincipal;
 
 public class LdapGroupDAOTest extends AbstractLdapDAOTest
 {
     private static final Logger log = Logger.getLogger(LdapGroupDAOTest.class);
     
-    static String daoTestDN1 = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
-    static String daoTestDN2 = "cn=cadcdaotest2,ou=cadc,o=hia,c=ca";
-    static String daoTestDN3 = "cn=cadcdaotest3,ou=cadc,o=hia,c=ca";
+    static String daoTestUid1 = "cadcdaotest1";
+    static String daoTestUid2 = "cadcdaotest2";
+    static String daoTestUid3 = "cadcdaotest3";
+    
+    static String daoTestDN1 = "cn=" + daoTestUid1 + ",ou=cadc,o=hia,c=ca";
+    static String daoTestDN2 = "cn=" + daoTestUid2 + ",ou=cadc,o=hia,c=ca";
+    static String daoTestDN3 = "cn=" + daoTestUid3 + ",ou=cadc,o=hia,c=ca";
     static String unknownDN = "cn=foo,ou=cadc,o=hia,c=ca";
     
     static X500Principal daoTestPrincipal1;
@@ -192,6 +196,18 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest
                     expectGroup.getUserMembers().add(daoTestUser2);
                     actualGroup = getGroupDAO().modifyGroup(expectGroup);
                     assertGroupsEqual(expectGroup, actualGroup);
+                    
+                    // test adding the same user but with two different
+                    // Principals. The duplicate should be ignored
+                    // the the returned result should contain only
+                    // one entry (the dn one)
+                    User<HttpPrincipal> duplicateIdentity = 
+                            new User<HttpPrincipal>(new HttpPrincipal(daoTestUid2));
+                    expectGroup.getUserMembers().add(daoTestUser2);
+                    expectGroup.getUserMembers().add(duplicateIdentity);
+                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
+                    expectGroup.getUserMembers().remove(duplicateIdentity);
+                    assertGroupsEqual(expectGroup, actualGroup);
 
                     expectGroup.getUserMembers().remove(daoTestUser2);
                     actualGroup = getGroupDAO().modifyGroup(expectGroup);
@@ -222,6 +238,16 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest
                     actualGroup = getGroupDAO().modifyGroup(expectGroup);
                     assertGroupsEqual(expectGroup, actualGroup);
 
+                    // test adding the same user admin but with two different
+                    // Principals. The duplicate should be ignored
+                    // the the returned result should contain only
+                    // one entry (the dn one)
+                    expectGroup.getUserAdmins().add(daoTestUser2);
+                    expectGroup.getUserAdmins().add(duplicateIdentity);
+                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
+                    expectGroup.getUserAdmins().remove(duplicateIdentity);
+                    assertGroupsEqual(expectGroup, actualGroup);
+                    
                     // delete the group
                     getGroupDAO().deleteGroup(expectGroup.getID());
                     try
@@ -240,8 +266,24 @@ public class LdapGroupDAOTest extends AbstractLdapDAOTest
                     actualGroup = getGroupDAO().getGroup(expectGroup.getID());
                     assertGroupsEqual(expectGroup, actualGroup);
                     
+                    // create another group and make expected group
+                    // member of that group. Delete expected group after
+                    Group expectGroup2 = new Group(getGroupID(), daoTestUser1);
+                    expectGroup2.getGroupAdmins().add(expectGroup);
+                    expectGroup2.getGroupMembers().add(expectGroup);
+                    Group actualGroup2 = getGroupDAO().addGroup(expectGroup2);
+                    log.debug("addGroup: " + expectGroup2.getID());
+                    assertGroupsEqual(expectGroup2, actualGroup2);
+                    
                     // delete the group
                     getGroupDAO().deleteGroup(expectGroup.getID());
+                    // now expectGroup should not be member of admin of 
+                    // expectGroup2
+                    expectGroup2.getGroupAdmins().remove(expectGroup);
+                    expectGroup2.getGroupMembers().remove(expectGroup);
+                    actualGroup2 = getGroupDAO().getGroup(expectGroup2.getID());
+                    log.debug("addGroup: " + expectGroup2.getID());
+                    assertGroupsEqual(expectGroup2, actualGroup2);
                     
                     return null;
                 }
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 7609ee7326133d0d2975059fdd7666c0e3435f0c..cb0ec4f65ed7605c44f0731fe0246200dccaf6cb 100755
--- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
+++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java
@@ -375,7 +375,7 @@ public class GMSClient
      * @throws AccessControlException If unauthorized to perform this operation.
      * @throws java.io.IOException
      */
-    public void updateGroup(Group group)
+    public Group updateGroup(Group group)
         throws IllegalArgumentException, GroupNotFoundException, UserNotFoundException,
                AccessControlException, IOException
     {
@@ -388,13 +388,12 @@ public class GMSClient
         StringBuilder groupXML = new StringBuilder();
         GroupWriter.write(group, groupXML);
         log.debug("updateGroup: " + groupXML);
-
+        
         HttpPost transfer = new HttpPost(updateGroupURL, groupXML.toString(), 
-                                         "application/xml", false);
-
+                                         "application/xml", true);
         transfer.setSSLSocketFactory(getSSLSocketFactory());
         transfer.run();
-
+        
         Throwable error = transfer.getThrowable();
         if (error != null)
         {
@@ -418,6 +417,18 @@ public class GMSClient
             }
             throw new IOException(error);
         }
+        
+        try
+        {
+            String retXML = transfer.getResponseBody();
+            log.debug("getGroup returned: " + retXML);
+            return GroupReader.read(retXML);
+        }
+        catch (Exception bug)
+        {
+            log.error("Unexpected exception", bug);
+            throw new RuntimeException(bug);
+        }
     }
 
     /**