diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java
index ad7838c4fbeef26b6dd1f9f1d7f21a6a376d1d14..caf9dc42cabef2c2ddb1cbf3af504742b05a9706 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java
@@ -68,16 +68,16 @@
  */
 package ca.nrc.cadc.ac.server;
 
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.Collection;
+
 import ca.nrc.cadc.ac.Group;
 import ca.nrc.cadc.ac.GroupAlreadyExistsException;
 import ca.nrc.cadc.ac.GroupNotFoundException;
-import ca.nrc.cadc.ac.IdentityType;
 import ca.nrc.cadc.ac.Role;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.net.TransientException;
-import java.security.AccessControlException;
-import java.security.Principal;
-import java.util.Collection;
 
 public abstract interface GroupPersistence<T extends Principal>
 {
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java
index e1ce4ab0f1177f53c3f89a5a05e4c6e342b1fce0..06d927727f067e0a18c14126b2d8d6338b9e4fff 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/PluginFactory.java
@@ -125,8 +125,8 @@ public class PluginFactory
         {
             try
             {
-                Class c = Class.forName(cname);
-                ret = (GroupPersistence) c.newInstance();
+                Class<?> c = Class.forName(cname);
+                ret = (GroupPersistence<T>) c.newInstance();
             }
             catch (Exception ex)
             {
@@ -149,8 +149,8 @@ public class PluginFactory
         {
             try
             {
-                Class c = Class.forName(cname);
-                ret = (UserPersistence) c.newInstance();
+                Class<?> c = Class.forName(cname);
+                ret = (UserPersistence<T>) c.newInstance();
             }
             catch (Exception ex)
             {
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java
index 4252ee66258973168f331a10d4dc42a4450cb3d3..11a7f00b07f5c951d20fc9a6ddf17cfaa4b997a9 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java
@@ -68,22 +68,26 @@
  */
 package ca.nrc.cadc.ac.server.ldap;
 
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+
 import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.auth.NumericPrincipal;
 import ca.nrc.cadc.auth.OpenIdPrincipal;
+import ca.nrc.cadc.net.TransientException;
+
 import com.unboundid.ldap.sdk.DN;
 import com.unboundid.ldap.sdk.LDAPConnection;
 import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.ResultCode;
 import com.unboundid.ldap.sdk.SearchResult;
 import com.unboundid.ldap.sdk.SearchResultEntry;
 import com.unboundid.ldap.sdk.SearchScope;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.Principal;
-import java.util.List;
-import java.util.Set;
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
 
 public abstract class LdapDAO
 {
@@ -116,7 +120,15 @@ public abstract class LdapDAO
         {
             conn = new LDAPConnection(config.getServer(), config.getPort());
             conn.bind(config.getAdminUserDN(), config.getAdminPasswd());
+        }
 
+        return conn;
+    }
+
+    protected DN getSubjectDN() throws LDAPException
+    {
+        if (subjDN == null)
+        {
             Subject callerSubject = 
                     Subject.getSubject(AccessController.getContext());
             if (callerSubject == null)
@@ -161,7 +173,7 @@ public abstract class LdapDAO
             }
 
             SearchResult searchResult = 
-                    conn.search(config.getUsersDN(), SearchScope.ONE, 
+                    getConnection().search(config.getUsersDN(), SearchScope.ONE, 
                                 ldapField, new String[] {"entrydn"});
 
             if (searchResult.getEntryCount() < 1)
@@ -173,17 +185,50 @@ public abstract class LdapDAO
             subjDN = ((SearchResultEntry) searchResult.getSearchEntries()
                     .get(0)).getAttributeValueAsDN("entrydn");
         }
-
-        return conn;
+        return subjDN;
     }
-
-    protected DN getSubjectDN() throws LDAPException
+    
+    /**
+     * Checks the Ldap result code, and if the result is not SUCCESS,
+     * throws an appropriate exception. This is the place to decide on 
+     * mapping between ldap errors and exception types
+     * @param code
+     * @param errorMsg
+     * @throws TransientException 
+     */
+    protected static void checkLdapResult(ResultCode code, String errorMsg) 
+            throws TransientException
     {
-        if (subjDN == null)
+        String msg = "";
+        if (errorMsg != null)
         {
-            getConnection();
+            msg = "(" + errorMsg + ")";
+        }
+        if (code == ResultCode.INSUFFICIENT_ACCESS_RIGHTS)
+        {
+            throw new AccessControlException("Not authorized " + msg);
+        }
+        else if (code == ResultCode.INVALID_CREDENTIALS)
+        {
+            throw new AccessControlException("Invalid credentials " + msg);
+        }
+        else if (code == ResultCode.SUCCESS)
+        {
+            // all good. nothing to do
+        }
+        else if (code == ResultCode.PARAM_ERROR)
+        {
+            throw new IllegalArgumentException("Error in Ldap parameters " + msg);
+        }
+        else if (code == ResultCode.BUSY ||
+                 code == ResultCode.CONNECT_ERROR )
+        {
+            throw new TransientException("Connection problems " + msg );
+        }
+        else
+        {
+            throw new RuntimeException("Ldap error" + msg);
         }
-        return subjDN;
     }
 
 }
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 d418cc36f9e6a9db5f7e7652839a744f78c5e296..15d6745c8d92e02772c906c5fe04a7d39e9358cd 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
@@ -94,9 +94,11 @@ import com.unboundid.ldap.sdk.DN;
 import com.unboundid.ldap.sdk.Filter;
 import com.unboundid.ldap.sdk.LDAPException;
 import com.unboundid.ldap.sdk.LDAPResult;
+import com.unboundid.ldap.sdk.LDAPSearchException;
 import com.unboundid.ldap.sdk.Modification;
 import com.unboundid.ldap.sdk.ModificationType;
 import com.unboundid.ldap.sdk.ModifyRequest;
+import com.unboundid.ldap.sdk.ResultCode;
 import com.unboundid.ldap.sdk.SearchRequest;
 import com.unboundid.ldap.sdk.SearchResult;
 import com.unboundid.ldap.sdk.SearchResultEntry;
@@ -122,7 +124,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
     }
 
     /**
-     * Creates the group.
+     * Persists a group.
      * 
      * @param group The group to create
      * 
@@ -142,6 +144,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             throw new IllegalArgumentException("Group owner must be specified");
         }
         
+        if (!group.getProperties().isEmpty())
+        {
+            throw new UnsupportedOperationException(
+                    "Support for groups properties not available");
+        }
+        
         if (!isCreatorOwner(group.getOwner()))
         {
             throw new AccessControlException("Group owner must be creator");
@@ -149,28 +157,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
 
         try
         {
-            getGroup(group.getID());
-            throw new GroupAlreadyExistsException(group.getID());
-        }
-        catch (GroupNotFoundException ex)
-        {
-            try
-            {        
-                if (!group.getProperties().isEmpty())
-                {
-                    throw new UnsupportedOperationException(
-                            "Support for groups properties not available");
-                }
-                
-                try
-                {
-                    getInactiveGroup(group);
-                    return reactivateGroup(group);
-                }
-                catch (GroupNotFoundException e)
-                {
-                    // ignore
-                }
+            Group newGroup = reactivateGroup(group);
+            if ( newGroup != null)
+            {
+                return newGroup;
+            }
+            else
+            {
                 
                 DN ownerDN = userPersist.getUserDN(group.getOwner());
                 
@@ -180,13 +173,15 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                                              group.description, 
                                              group.getUserMembers(), 
                                              group.getGroupMembers());
+                LdapDAO.checkLdapResult(result.getResultCode(), null);
                 
                 // add group to admin groups tree
                 result = addGroup(getAdminGroupDN(group.getID()), 
                                   group.getID(), ownerDN, 
                                   group.description, 
-                                  group.getUserMembers(), 
-                                  group.getGroupMembers());
+                                  group.getUserAdmins(), 
+                                  group.getGroupAdmins());
+                LdapDAO.checkLdapResult(result.getResultCode(), null);
                 
                 try
                 {
@@ -197,19 +192,20 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                     throw new RuntimeException("BUG: new group not found");
                 }
             }
-            catch (LDAPException e)
-            {
-                e.printStackTrace();
-                throw new RuntimeException(e);
-            } 
         }
+        catch (LDAPException e)
+        {
+            LdapDAO.checkLdapResult(e.getResultCode(), 
+                    e.getDiagnosticMessage());
+            throw new RuntimeException("Unexpected LDAP exception", e);
+        } 
     }
     
     private LDAPResult addGroup(final DN groupDN, final String groupID,
                                 final DN ownerDN, final String description, 
                                 final Set<User<? extends Principal>> users, 
                                 final Set<Group> groups)
-        throws UserNotFoundException, LDAPException
+        throws UserNotFoundException, LDAPException, TransientException
     {
         // add new group
         List<Attribute> attributes = new ArrayList<Attribute>();
@@ -242,7 +238,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         }
 
         AddRequest addRequest = new AddRequest(groupDN, attributes);
-
         addRequest.addControl(
                 new ProxiedAuthorizationV2RequestControl(
                         "dn:" + getSubjectDN().toNormalizedString()));
@@ -250,89 +245,66 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         return getConnection().add(addRequest);
     }
     
-    private Group getInactiveGroup(final Group group)
+    
+    /**
+     * Checks whether group name available for the user or already in use.
+     * @param group
+     * @return activated group or null if group does not exists
+     * @throws AccessControlException
+     * @throws UserNotFoundException
+     * @throws GroupNotFoundException
+     * @throws TransientException
+     * @throws GroupAlreadyExistsException 
+     */
+    private Group reactivateGroup(final Group group)
         throws AccessControlException, UserNotFoundException,
-        GroupNotFoundException
+        TransientException, GroupAlreadyExistsException
     {
-        Group inactiveGroup;
         try
         {
-            inactiveGroup = getInactiveGroup(
-                    getGroupDN(group.getID()), group.getID());
+            // check group name exists           
+            Filter filter = Filter.createEqualityFilter("cn", group.getID());
+
+            SearchRequest searchRequest = 
+                    new SearchRequest(
+                            getGroupDN(group.getID())
+                            .toNormalizedString(), SearchScope.SUB, filter, 
+                                      new String[] {"nsaccountlock"});
+
+            searchRequest.addControl(
+                    new ProxiedAuthorizationV2RequestControl("dn:" + 
+                            getSubjectDN().toNormalizedString()));
 
-            if (inactiveGroup == null)
+            SearchResultEntry searchResult = 
+                    getConnection().searchForEntry(searchRequest);
+            
+            if (searchResult == null)
             {
                 return null;
             }
 
-            if (!group.getOwner().equals(inactiveGroup.getOwner()))
+            if (searchResult.getAttributeValue("nsaccountlock") == null)
             {
-                throw new AccessControlException(
-                        "Inactive group not owned be requestor");
+                throw new 
+                GroupAlreadyExistsException("Group already exists " + group.getID());
             }
-
-            Group inactiveAdminGroup = getInactiveGroup(
-                    getAdminGroupDN(group.getID()), group.getID());
-
-            if (inactiveAdminGroup == null)
+            
+            // activate group            
+            try
             {
-                throw new RuntimeException(
-                        "BUG: adminGroup not found for group " + group.getID());
-            }
-
-            if (!group.getOwner().equals(inactiveAdminGroup.getOwner()))
+                return modifyGroup(group, true);
+            } 
+            catch (GroupNotFoundException e)
             {
                 throw new RuntimeException(
-                        "Bug: adminGroup owner doesn't match "
-                                + "group owner for group " + group.getID());
-            }
-            return inactiveGroup;
+                        "BUG: group to modify does not exist" + group.getID());
+            }          
         } 
         catch (LDAPException e)
         {
-            // TODO Auto-generated catch block
-            throw new RuntimeException("BUG: LDAP Exception: ", e);
-        }
-    }
-    
-    private Group getInactiveGroup(final DN groupDN, final String groupID)
-        throws UserNotFoundException, LDAPException, GroupNotFoundException
-    {
-        Filter filter = Filter.createANDFilter(
-                Filter.createEqualityFilter("cn", groupID),
-                Filter.createEqualityFilter("nsaccountlock", "true"));
-
-        SearchRequest searchRequest = 
-                new SearchRequest(groupDN.toNormalizedString(), SearchScope.SUB,
-                                  filter, new String[] {"cn", "owner"});
-
-        searchRequest.addControl(
-                new ProxiedAuthorizationV2RequestControl("dn:" + 
-                        getSubjectDN().toNormalizedString()));
-
-        SearchResultEntry searchResult = 
-                getConnection().searchForEntry(searchRequest);
-        
-        if (searchResult == null)
-        {
-            String msg = "Inactive Group not found " + groupID;
-            logger.debug(msg);
-            throw new GroupNotFoundException(msg);
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
+            throw new RuntimeException("Unexpected LDAP exception", e);
         }
-
-        String groupCN = searchResult.getAttributeValue("cn");
-        DN groupOwner = searchResult.getAttributeValueAsDN("owner");
-
-        User<X500Principal> owner = userPersist.getMember(groupOwner);
-
-        return new Group(groupCN, owner);
-    }
-    
-    private Group reactivateGroup(final Group group)
-        throws UserNotFoundException, LDAPException, TransientException, 
-               AccessControlException, GroupNotFoundException
-    {
-        return modifyGroup(group, true);
     }
 
     /**
@@ -407,18 +379,44 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                     new ProxiedAuthorizationV2RequestControl("dn:" + 
                             getSubjectDN().toNormalizedString()));
 
-            SearchResultEntry searchResult = 
-                    getConnection().searchForEntry(searchRequest);
+            SearchResult searchResult = null;
+            try
+            {
+                searchResult = getConnection().search(searchRequest);
+            }
+            catch (LDAPSearchException e)
+            {
+                if (e.getResultCode() == ResultCode.AUTHORIZATION_DENIED)
+                {
+                    throw new AccessControlException("Unauthorized to access group " + groupID);
+                }
+                else if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT)
+                {
+                    String msg = "Group not found " + groupID;
+                    logger.debug(msg);
+                    throw new GroupNotFoundException(groupID);
+                }
+                else
+                {
+                    throw new RuntimeException("Unknown LDAP exception: " + e.getResultCode());
+                }
+            }
             
-            if (searchResult == null)
+            if (searchResult.getEntryCount() == 0)
             {
+                // deleted groups?
                 String msg = "Group not found " + groupID;
                 logger.debug(msg);
                 throw new GroupNotFoundException(groupID);
             }
             
-            String groupCN = searchResult.getAttributeValue("cn");
-            DN groupOwner = searchResult.getAttributeValueAsDN("owner");
+            if (searchResult.getEntryCount() >1)
+            {
+                throw new RuntimeException("BUG: multiple results when retrieving group " + groupID);
+            }
+            SearchResultEntry searchEntry = searchResult.getSearchEntries().get(0);
+            String groupCN = searchEntry.getAttributeValue("cn");
+            DN groupOwner = searchEntry.getAttributeValueAsDN("owner");
             
             User<X500Principal> owner;
             try
@@ -431,22 +429,22 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             }
             
             Group ldapGroup = new Group(groupCN, owner);
-            if (searchResult.hasAttribute("description"))
+            if (searchEntry.hasAttribute("description"))
             {
                 ldapGroup.description = 
-                        searchResult.getAttributeValue("description");
+                        searchEntry.getAttributeValue("description");
             }
-            if (searchResult.hasAttribute("modifytimestamp"))
+            if (searchEntry.hasAttribute("modifytimestamp"))
             {
                 ldapGroup.lastModified = 
-                        searchResult.getAttributeValueAsDate("modifytimestamp");
+                        searchEntry.getAttributeValueAsDate("modifytimestamp");
             }
 
             if (withMembers)
             {
-                if (searchResult.getAttributeValues("uniquemember") != null)
+                if (searchEntry.getAttributeValues("uniquemember") != null)
                 {
-                    for (String member : searchResult
+                    for (String member : searchEntry
                             .getAttributeValues("uniquemember"))
                     {
                         DN memberDN = new DN(member);
@@ -483,10 +481,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         }
         catch (LDAPException e1)
         {
-            // TODO check which LDAP exceptions are transient and which
-            // ones are
-            // access control
-            throw new TransientException("Error getting the group", e1);
+            LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage());
+            throw new GroupNotFoundException("Not found " + groupID);
         }
     }
 
@@ -506,6 +502,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         throws GroupNotFoundException, TransientException,
                AccessControlException, UserNotFoundException
     {
+        getGroup(group.getID()); //group must exists first
         return modifyGroup(group, false); 
     }
     
@@ -518,16 +515,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             throw new UnsupportedOperationException(
                     "Support for groups properties not available");
         }
-        
-        // check if group exists
-        if (withActivate)
-        {
-            getInactiveGroup(group);
-        }
-        else
-        {
-            getGroup(group.getID());
-        }
 
         List<Modification> mods = new ArrayList<Modification>();
         List<Modification> adminMods = new ArrayList<Modification>();
@@ -549,16 +536,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         List<String> newMembers = new ArrayList<String>();
         for (User<?> member : group.getUserMembers())
         {
-            DN memberDN;
-            try
-            {
-                memberDN = userPersist.getUserDN(member);
-            } 
-            catch (LDAPException e)
-            {
-                throw new UserNotFoundException("User not found "
-                        + member.getUserID());
-            }
+            DN memberDN = userPersist.getUserDN(member);
             newMembers.add(memberDN.toNormalizedString());
         }
         for (Group gr : group.getGroupMembers())
@@ -569,16 +547,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         List<String> newAdmins = new ArrayList<String>();
         for (User<?> member : group.getUserAdmins())
         {
-            DN memberDN;
-            try
-            {
-                memberDN = userPersist.getUserDN(member);
-            }
-            catch (LDAPException e)
-            {
-                throw new UserNotFoundException(
-                        "User not found " + member.getUserID());
-            }
+            DN memberDN = userPersist.getUserDN(member);
             newAdmins.add(memberDN.toNormalizedString());
         }
         for (Group gr : group.getGroupAdmins())
@@ -599,24 +568,21 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             modifyRequest.addControl(
                     new ProxiedAuthorizationV2RequestControl(
                             "dn:" + getSubjectDN().toNormalizedString()));
-            LDAPResult result = getConnection().modify(modifyRequest);
-        }
-        catch (LDAPException e1)
-        {
-            throw new RuntimeException("LDAP problem", e1);
-        }
-        // modify the group itself now
-        modifyRequest = new ModifyRequest(getGroupDN(group.getID()), mods);
-        try
-        {
+            LdapDAO.checkLdapResult(getConnection().
+                    modify(modifyRequest).getResultCode(), null);
+            
+            // modify the group itself now
+            modifyRequest = new ModifyRequest(getGroupDN(group.getID()), mods);
+
             modifyRequest.addControl(
                     new ProxiedAuthorizationV2RequestControl(
                             "dn:" + getSubjectDN().toNormalizedString()));
-            LDAPResult result = getConnection().modify(modifyRequest);
+            LdapDAO.checkLdapResult(getConnection().
+                    modify(modifyRequest).getResultCode(), null);
         }
         catch (LDAPException e1)
         {
-            throw new RuntimeException("LDAP problem", e1);
+            LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage());
         }
         try
         {
@@ -685,10 +651,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                     new ProxiedAuthorizationV2RequestControl(
                             "dn:" + getSubjectDN().toNormalizedString()));
             LDAPResult result = getConnection().modify(modifyRequest);
+            LdapDAO.checkLdapResult(result.getResultCode(), null);
         }
         catch (LDAPException e1)
         {
-            throw new RuntimeException("LDAP problem", e1);
+            LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage());
         }
         
         try
@@ -721,18 +688,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                GroupNotFoundException, UserNotFoundException
     {
         User<T> user = new User<T>(userID);
-        DN userDN;
-        try
-        {   
-            userDN = userPersist.getUserDN(user);
-        }
-        catch (LDAPException e)
-        {
-            // TODO check which LDAP exceptions are transient and which
-            // ones are
-            // access control
-            throw new TransientException("Error getting user", e);
-        }
+        DN userDN = userPersist.getUserDN(user);
         
         Collection<DN> groupDNs = new HashSet<DN>();
         if (role == Role.OWNER)
@@ -769,6 +725,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         throws TransientException, AccessControlException,
                GroupNotFoundException, UserNotFoundException
     {
+        Collection<DN> groupDNs = new HashSet<DN>();
         try
         {                           
             Filter filter = Filter.createEqualityFilter("owner", 
@@ -787,22 +744,18 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
                     new ProxiedAuthorizationV2RequestControl("dn:" + 
                             getSubjectDN().toNormalizedString()));
             
-            Collection<DN> groupDNs = new HashSet<DN>();
             SearchResult results = getConnection().search(searchRequest);
             for (SearchResultEntry result : results.getSearchEntries())
             {
                 String entryDN = result.getAttributeValue("entrydn");
                 groupDNs.add(new DN(entryDN));
             }
-            return groupDNs; 
         }
         catch (LDAPException e1)
         {
-            // TODO check which LDAP exceptions are transient and which
-            // ones are
-            // access control
-            throw new TransientException("Error getting groups", e1);
+            LdapDAO.checkLdapResult(e1.getResultCode(), e1.getDiagnosticMessage());
         }
+        return groupDNs; 
     }
     
     protected Collection<DN> getMemberGroups(final User<T> user, 
@@ -812,7 +765,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         throws TransientException, AccessControlException,
                GroupNotFoundException, UserNotFoundException
     {
-        Collection<DN> groups = new HashSet<DN>();
+        Collection<DN> groupDNs = new HashSet<DN>();
         if (groupID != null)
         {
             DN groupDN;
@@ -827,17 +780,16 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
             if (userPersist.isMember(user.getUserID(),
                                      groupDN.toNormalizedString()))
             {
-                groups.add(groupDN);
+                groupDNs.add(groupDN);
             }
         }
         else
         {
             Collection<DN> memberGroupDNs = 
                     userPersist.getUserGroups(user.getUserID(), isAdmin);
-            groups.addAll(memberGroupDNs);
-            logger.debug("# groups found: " + memberGroupDNs.size());
+            groupDNs.addAll(memberGroupDNs);
         }
-        return groups;
+        return groupDNs;
     }
     
     /**
@@ -873,7 +825,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
      * @param groupID
      * @return 
      */
-    protected DN getGroupDN(final String groupID)
+    protected DN getGroupDN(final String groupID) throws TransientException
     {
         try
         {
@@ -881,6 +833,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         }
         catch (LDAPException e)
         {
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
         }
         throw new IllegalArgumentException(groupID + " not a valid group ID");
     }
@@ -890,7 +843,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
      * @param groupID
      * @return 
      */
-    protected DN getAdminGroupDN(final String groupID)
+    protected DN getAdminGroupDN(final String groupID) throws TransientException
     {
         try
         {
@@ -898,6 +851,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
         }
         catch (LDAPException e)
         {
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
         }
         throw new IllegalArgumentException(groupID + " not a valid group ID");
     }
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 3c0a0e7392f5e5d86c7a40722d31620dd9d79e5d..88e16fee18d8e8cd6d322219532a948a57a1118f 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
@@ -84,7 +84,6 @@ import ca.nrc.cadc.ac.PersonalDetails;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.auth.NumericPrincipal;
 import ca.nrc.cadc.net.TransientException;
 
 import com.unboundid.ldap.sdk.CompareRequest;
@@ -167,7 +166,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
         }
         catch (LDAPException e)
         {
-            e.printStackTrace();
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
         }
 
         if (searchResult == null)
@@ -203,6 +202,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     public Collection<DN> getUserGroups(final T userID, final boolean isAdmin)
         throws UserNotFoundException, TransientException, AccessControlException
     {
+        Collection<DN> groupDNs = new HashSet<DN>();
         try
         {
             String searchField = (String) userLdapAttrib.get(userID.getClass());
@@ -239,7 +239,6 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                 parentDN = new DN(config.getGroupsDN());
             }
             
-            Collection<DN> groupDNs = new HashSet<DN>();
             if (searchResult != null)
             {
                 String[] members = searchResult.getAttributeValues("memberOf");
@@ -254,17 +253,13 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                         }
                     }
                 }
-            }
-            return groupDNs;
+            } 
         }
         catch (LDAPException e)
         {
-            e.printStackTrace();
-            // TODO check which LDAP exceptions are transient and which
-            // ones are
-            // access control
-            throw new TransientException("Error getting user groups", e);
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
         }
+        return groupDNs;
     }
     
     /**
@@ -315,15 +310,48 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
             }
             return true;
         }
-        catch (LDAPException e1)
+        catch (LDAPException e)
         {
-            // TODO check which LDAP exceptions are transient and which
-            // ones are
-            // access control
-            throw new TransientException("Error getting the user", e1);
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
         }
+        return false;
     }
     
+//    public boolean isMember(T userID, String groupID)
+//        throws UserNotFoundException, TransientException,
+//               AccessControlException
+//    {
+//        try
+//        {
+//            String searchField = (String) userLdapAttrib.get(userID.getClass());
+//            if (searchField == null)
+//            {
+//                throw new IllegalArgumentException(
+//                        "Unsupported principal type " + userID.getClass());
+//            }
+//
+//            User<T> user = getUser(userID);
+//            DN userDN = getUserDN(user);
+//
+//            CompareRequest compareRequest = 
+//                    new CompareRequest(userDN.toNormalizedString(), 
+//                                      "memberOf", groupID);
+//            
+//            compareRequest.addControl(
+//                    new ProxiedAuthorizationV2RequestControl("dn:" + 
+//                            getSubjectDN().toNormalizedString()));
+//            
+//            CompareResult compareResult = 
+//                    getConnection().compare(compareRequest);
+//            return compareResult.compareMatched();
+//        }
+//        catch (LDAPException e)
+//        {
+//            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
+//            throw new RuntimeException("Unexpected LDAP exception", e);
+//        }
+//    }
+    
     /**
      * Returns a member user identified by the X500Principal only. The
      * returned object has the fields required by the GMS.
@@ -371,7 +399,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     
 
     DN getUserDN(User<? extends Principal> user)
-        throws LDAPException, UserNotFoundException
+        throws UserNotFoundException, TransientException
     {
         String searchField = (String) userLdapAttrib.get(user.getUserID().getClass());
         if (searchField == null)
@@ -383,17 +411,22 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
         searchField = "(" + searchField + "=" + 
                       user.getUserID().getName() + ")";
 
-        SearchRequest searchRequest = 
-                new SearchRequest(this.config.getUsersDN(), SearchScope.SUB, 
-                                 searchField, new String[] {"entrydn"});
+        SearchResultEntry searchResult = null;
+        try
+        {
+            SearchRequest searchRequest = new SearchRequest(this.config.getUsersDN(), SearchScope.SUB, 
+                             searchField, new String[] {"entrydn"});
         
-//        searchRequest.addControl(
-//                    new ProxiedAuthorizationV2RequestControl("dn:" + 
-//                            getSubjectDN().toNormalizedString()));
 
-        SearchResultEntry searchResult = 
+            searchResult = 
                 getConnection().searchForEntry(searchRequest);
 
+        } catch (LDAPException e)
+        {
+            LdapDAO.checkLdapResult(e.getResultCode(), e.getDiagnosticMessage());
+        }
+        
+
         if (searchResult == null)
         {
             String msg = "User not found " + user.getUserID().toString();
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 2c68a1e61958dac8d9dd2bb946d114eff633330b..7d2f9b99416c61141591114f0014df66a10e2b1f 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
@@ -719,6 +719,32 @@ public class LdapGroupDAOTest
                 return null;
             }
         });
+        
+        
+        // change the user
+        Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>()
+        {
+            
+            public Object run() throws Exception
+            {
+
+                
+                try
+                {
+                    Group group = getGroupDAO().getGroup(groupID);
+                    assertTrue(group == null);
+                    
+                    fail("searchGroups with unknown user should throw " + 
+                         "GroupNotFoundException");
+                }
+                catch (GroupNotFoundException ignore) 
+                {
+
+                }
+
+                return null;
+            }
+        });
     }
 
     private void assertGroupsEqual(Group gr1, Group gr2)