diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionPool.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionPool.java
index ea65ec8f17f8d5e2d4cb7a6176e4d7a6af478948..37482c058b8e85063d93f029539e9bd32eed84c8 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionPool.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionPool.java
@@ -100,6 +100,13 @@ public class LdapConnectionPool
 {
     private static final Logger logger = Logger.getLogger(LdapConnectionPool.class);
 
+    private enum SystemState
+    {
+        ONLINE,
+        READONLY,
+        OFFLINE
+    };
+
     Profiler profiler = new Profiler(LdapConnectionPool.class);
 
     protected LdapConfig currentConfig;
@@ -107,8 +114,10 @@ public class LdapConnectionPool
     private LDAPConnectionPool pool;
     private Object poolMonitor = new Object();
     private LDAPConnectionOptions connectionOptions;
+    private boolean readOnly;
+    SystemState systemState = SystemState.ONLINE;
 
-    public LdapConnectionPool(LdapConfig config, LdapPool poolConfig, String poolName, boolean boundPool)
+    public LdapConnectionPool(LdapConfig config, LdapPool poolConfig, String poolName, boolean boundPool, boolean readOnly)
     {
         if (config == null)
             throw new IllegalArgumentException("config required");
@@ -122,19 +131,49 @@ public class LdapConnectionPool
         connectionOptions.setAutoReconnect(true);
         currentConfig = config;
         this.poolName = poolName;
-        synchronized (poolMonitor)
+        this.readOnly = readOnly;
+
+        systemState = getSystemState(config);
+        logger.debug("Construct pool: " + poolName + ". system state: " + systemState);
+        if (SystemState.ONLINE.equals(systemState) || (SystemState.READONLY.equals(systemState) && readOnly))
         {
-            if (!boundPool)
-                pool = createPool(config, poolConfig, poolName, null, null);
-            else
-                pool = createPool(config, poolConfig, poolName, config.getAdminUserDN(), config.getAdminPasswd());
-            logger.debug(poolName + " statistics after create:\n" + pool.getConnectionPoolStatistics());
-            profiler.checkpoint("Create read only pool.");
+            synchronized (poolMonitor)
+            {
+                if (!boundPool)
+                    pool = createPool(config, poolConfig, poolName, null, null);
+                else
+                    pool = createPool(config, poolConfig, poolName, config.getAdminUserDN(), config.getAdminPasswd());
+
+                if (pool != null)
+                {
+                    logger.debug(poolName + " statistics after create:\n" + pool.getConnectionPoolStatistics());
+                    profiler.checkpoint("Create read only pool.");
+                }
+            }
+        }
+        else
+        {
+            logger.debug("Not creating pool " + poolName + " because system state is " + systemState);
         }
     }
 
     public LDAPConnection getConnection() throws TransientException
     {
+
+        logger.debug("Get connection: " + poolName + ". system state: " + systemState);
+        if (SystemState.OFFLINE.equals(systemState))
+        {
+            throw new TransientException("The system is down for maintenance.", 600);
+        }
+
+        if (SystemState.READONLY.equals(systemState))
+        {
+            if (!readOnly)
+            {
+                throw new TransientException("The system is in read-only mode.", 600);
+            }
+        }
+
         try
         {
             LDAPConnection conn = null;
@@ -169,8 +208,11 @@ public class LdapConnectionPool
 
     public void releaseConnection(LDAPConnection conn)
     {
-        pool.releaseConnection(conn);
-        logger.debug(poolName + " pool statistics after release:\n" + pool.getConnectionPoolStatistics());
+        if (pool != null)
+        {
+            pool.releaseConnection(conn);
+            logger.debug(poolName + " pool statistics after release:\n" + pool.getConnectionPoolStatistics());
+        }
     }
 
     public LdapConfig getCurrentConfig()
@@ -180,9 +222,12 @@ public class LdapConnectionPool
 
     public void shutdown()
     {
-        logger.debug("Closing pool...");
-        pool.close();
-        profiler.checkpoint("Pool closed.");
+        if (pool != null)
+        {
+            logger.debug("Closing pool...");
+            pool.close();
+            profiler.checkpoint("Pool closed.");
+        }
     }
 
     public String getName()
@@ -191,7 +236,6 @@ public class LdapConnectionPool
     }
 
     private LDAPConnectionPool createPool(LdapConfig config, LdapPool poolConfig, String poolName, String bindID, String bindPW)
-
     {
         try
         {
@@ -245,4 +289,32 @@ public class LdapConnectionPool
     }
 
 
+    /**
+     * Check if in read-only or offline mode.
+     *
+     * A read max connection size of zero implies offline mode.
+     * A read-wrtie max connection size of zero implies read-only mode.
+     */
+    private SystemState getSystemState(LdapConfig config)
+    {
+
+        if (config.getReadOnlyPool().getMaxSize() == 0)
+        {
+            return SystemState.OFFLINE;
+        }
+
+        if (config.getUnboundReadOnlyPool().getMaxSize() == 0)
+        {
+            return SystemState.OFFLINE;
+        }
+
+        if (config.getReadWritePool().getMaxSize() == 0)
+        {
+            return SystemState.READONLY;
+        }
+
+        return SystemState.ONLINE;
+    }
+
+
 }
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnections.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnections.java
index 0884176f27d2ad55d384f50b25b575081853746d..cf5451e997fc29f48711ae72f3a77586669975c2 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnections.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapConnections.java
@@ -147,7 +147,7 @@ class LdapConnections
         {
             if (readOnlyPool == null)
             {
-                readOnlyPool = new LdapConnectionPool(config, config.getReadOnlyPool(), LdapPersistence.POOL_READONLY, true);
+                readOnlyPool = new LdapConnectionPool(config, config.getReadOnlyPool(), LdapPersistence.POOL_READONLY, true, true);
             }
             if (manualConfigReadOnlyConn == null)
             {
@@ -186,7 +186,7 @@ class LdapConnections
         {
             if (readWritePool == null)
             {
-                readWritePool = new LdapConnectionPool(config, config.getReadWritePool(), LdapPersistence.POOL_READWRITE, true);
+                readWritePool = new LdapConnectionPool(config, config.getReadWritePool(), LdapPersistence.POOL_READWRITE, true, false);
             }
             if (manualConfigReadWriteConn == null)
             {
@@ -225,7 +225,7 @@ class LdapConnections
         {
             if (unboundReadOnlyPool == null)
             {
-                unboundReadOnlyPool = new LdapConnectionPool(config, config.getUnboundReadOnlyPool(), LdapPersistence.POOL_UNBOUNDREADONLY, false);
+                unboundReadOnlyPool = new LdapConnectionPool(config, config.getUnboundReadOnlyPool(), LdapPersistence.POOL_UNBOUNDREADONLY, false, true);
             }
             if (manualConfigUnboundReadOnlyConn == null)
             {
@@ -317,4 +317,5 @@ class LdapConnections
             return config;
     }
 
+
 }
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java
index f81f012724ab5581c9dba368d4103a1dbddc84dc..50e9176bd5b77722124391c49e52fdcaf9fa696b 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java
@@ -70,7 +70,13 @@ package ca.nrc.cadc.ac.server.ldap;
 
 import java.security.AccessControlException;
 import java.security.Principal;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.security.auth.Subject;
 
 import org.apache.log4j.Logger;
 
@@ -87,11 +93,6 @@ import ca.nrc.cadc.auth.AuthMethod;
 import ca.nrc.cadc.auth.AuthenticationUtil;
 import ca.nrc.cadc.auth.DNPrincipal;
 import ca.nrc.cadc.net.TransientException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import javax.security.auth.Subject;
 
 public class LdapGroupPersistence<T extends Principal> extends LdapPersistence implements GroupPersistence<T>
 {
@@ -125,7 +126,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         LdapGroupDAO<T> groupDAO = null;
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
@@ -148,7 +149,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
     {
         Subject callerSubject = AuthenticationUtil.getCurrentSubject();
         boolean allowed = isMember(callerSubject, groupName) || isAdmin(callerSubject, groupName);
-        
+
         LdapGroupDAO<T> groupDAO = null;
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
@@ -175,7 +176,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
         Subject caller = AuthenticationUtil.getCurrentSubject();
         User<Principal> owner = getUser(caller);
         group.setOwner(owner);
-        
+
         LdapConnections conns = new LdapConnections(this);
         try
         {
@@ -194,7 +195,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
                AccessControlException
     {
         Subject callerSubject = AuthenticationUtil.getCurrentSubject();
-        
+
         LdapGroupDAO<T> groupDAO = null;
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
@@ -203,7 +204,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
             userDAO = new LdapUserDAO<T>(conns);
             groupDAO = new LdapGroupDAO<T>(conns, userDAO);
             Group g = groupDAO.getGroup(groupName, false);
-            if (isOwner(callerSubject, g)) 
+            if (isOwner(callerSubject, g))
                 groupDAO.deleteGroup(groupName);
             else
                 throw new AccessControlException("permission denied");
@@ -220,7 +221,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
     {
         Subject callerSubject = AuthenticationUtil.getCurrentSubject();
         boolean allowed = isAdmin(callerSubject, group.getID());
-        
+
         LdapGroupDAO<T> groupDAO = null;
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
@@ -247,27 +248,27 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
     }
 
     /**
-     * 
+     *
      * @param role
      * @param groupID check membership in a specific group or null to get all groups
      * @return
      * @throws UserNotFoundException
      * @throws GroupNotFoundException
      * @throws TransientException
-     * @throws AccessControlException 
+     * @throws AccessControlException
      */
     public Collection<Group> getGroups(Role role, String groupID)
         throws UserNotFoundException, GroupNotFoundException,
                TransientException, AccessControlException
     {
         Subject caller = AuthenticationUtil.getCurrentSubject();
-            
+
         LdapConnections conns = new LdapConnections(this);
         try
         {
             LdapUserDAO<T> userDAO = new LdapUserDAO<T>(conns);
             LdapGroupDAO<T>  groupDAO = new LdapGroupDAO<T>(conns, userDAO);
-            
+
             if ( Role.OWNER.equals(role))
             {
                 DNPrincipal p = getInternalID(caller);
@@ -316,20 +317,20 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
             conns.releaseConnections();
         }
     }
-    
+
     // GroupMemberships cache created by AuthenticatorImpl
     private List<Group> getGroupCache(Subject caller, Role role)
     {
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         Set<GroupMemberships> gset = caller.getPrivateCredentials(GroupMemberships.class);
         if (gset == null || gset.isEmpty())
             throw new RuntimeException("BUG: no GroupMemberships cache in Subject");
         GroupMemberships gms = gset.iterator().next();
         return gms.getMemberships(role);
     }
-    
+
     // true if the current subject is a member: using GroupMemberships cache
     private boolean isMember(Subject caller, String groupName)
     {
@@ -341,7 +342,7 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
         }
         return false;
     }
-    
+
     private boolean isAdmin(Subject caller, String groupName)
     {
         List<Group> groups = getGroupCache(caller, Role.ADMIN);
@@ -352,12 +353,12 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
         }
         return false;
     }
-    
+
     private boolean isOwner(Subject caller, Group g)
     {
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         // check owner
         for (Principal pc : caller.getPrincipals())
         {
@@ -374,18 +375,18 @@ public class LdapGroupPersistence<T extends Principal> extends LdapPersistence i
     {
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         Set<DNPrincipal> ds = caller.getPrincipals(DNPrincipal.class);
         if (ds.isEmpty())
             return null;
         return ds.iterator().next();
     }
-    
+
     private User<Principal> getUser(Subject caller)
     {
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         Set<GroupMemberships> gset = caller.getPrivateCredentials(GroupMemberships.class);
         if (gset == null || gset.isEmpty())
             throw new RuntimeException("BUG: no GroupMemberships cache in Subject");
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapPersistence.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapPersistence.java
index a8f2b0cebe16cd628c8b8d81315912b3a80854bf..2e7c75da3e6bdd3cc2caf746ebcd16a461189415 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapPersistence.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapPersistence.java
@@ -115,7 +115,7 @@ public abstract class LdapPersistence
             ConnectionPools pools = lookupPools();
             if (pools == null || pools.isClosed())
                 throw new IllegalStateException("Pools are closed.");
-            poolCheck(pools);
+            pools = poolCheck(pools);
             return pools.getPools().get(poolName);
         }
         catch (NamingException e)
@@ -240,11 +240,11 @@ public abstract class LdapPersistence
     {
         Map<String,LdapConnectionPool> poolMap = new HashMap<String,LdapConnectionPool>(3);
         poolMap.put(POOL_READONLY, new LdapConnectionPool(
-            config, config.getReadOnlyPool(), POOL_READONLY, true));
+            config, config.getReadOnlyPool(), POOL_READONLY, true, true));
         poolMap.put(POOL_READWRITE, new LdapConnectionPool(
-            config, config.getReadWritePool(), POOL_READWRITE, true));
+            config, config.getReadWritePool(), POOL_READWRITE, true, false));
         poolMap.put(POOL_UNBOUNDREADONLY, new LdapConnectionPool(
-            config, config.getUnboundReadOnlyPool(), POOL_UNBOUNDREADONLY, false));
+            config, config.getUnboundReadOnlyPool(), POOL_UNBOUNDREADONLY, false, true));
         profiler.checkpoint("Created 3 LDAP connection pools");
         return new ConnectionPools(poolMap, config);
     }
@@ -262,7 +262,7 @@ public abstract class LdapPersistence
         }
     }
 
-    private void poolCheck(ConnectionPools pools) throws TransientException
+    private ConnectionPools poolCheck(ConnectionPools pools) throws TransientException
     {
         if (timeToCheckPools(pools))
         {
@@ -278,6 +278,7 @@ public abstract class LdapPersistence
                 logger.debug("Detected ldap configuration change, rebuilding pools");
                 boolean poolRecreated = false;
                 final ConnectionPools oldPools = pools;
+                ConnectionPools newPools = null;
 
                 synchronized (jndiMonitor)
                 {
@@ -287,7 +288,7 @@ public abstract class LdapPersistence
                     {
                         try
                         {
-                            ConnectionPools newPools = createPools(newConfig);
+                            newPools = createPools(newConfig);
                             newPools.setLastPoolCheck(System.currentTimeMillis());
                             InitialContext ic = new InitialContext();
                             try
@@ -326,9 +327,13 @@ public abstract class LdapPersistence
                     };
                     Thread closePoolsThread = new Thread(closeOldPools);
                     closePoolsThread.start();
+
+                    return newPools;
                 }
             }
         }
+        // just return the existing pools
+        return pools;
     }
 
     private boolean timeToCheckPools(ConnectionPools pools)
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
index add4f8246ed770e19a25a29c19353952dda6aaff..b3d24cd5f2f815dbd375e032ff5a2ab5eb6f77f0 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
@@ -72,6 +72,8 @@ import java.security.AccessControlException;
 import java.security.Principal;
 import java.util.Collection;
 
+import javax.security.auth.Subject;
+
 import org.apache.log4j.Logger;
 
 import ca.nrc.cadc.ac.User;
@@ -85,8 +87,6 @@ import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
 import ca.nrc.cadc.profiler.Profiler;
 
-import javax.security.auth.Subject;
-
 public class LdapUserPersistence<T extends Principal> extends LdapPersistence implements UserPersistence<T>
 {
     private static final Logger logger = Logger.getLogger(LdapUserPersistence.class);
@@ -173,7 +173,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if ( !isMatch(caller, userID) )
             throw new AccessControlException("permission denied: target user does not match current user");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
@@ -186,7 +186,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
             conns.releaseConnections();
         }
     }
-    
+
     /**
      * Get the user specified by email address exists in the active users tree.
      *
@@ -200,7 +200,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
      * @throws UserAlreadyExistsException A user with the same email address already exists
      */
     public User<Principal> getUserByEmailAddress(String emailAddress)
-            throws UserNotFoundException, TransientException, 
+            throws UserNotFoundException, TransientException,
             AccessControlException, UserAlreadyExistsException
         {
             LdapConnections conns = new LdapConnections(this);
@@ -230,7 +230,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if ( !isMatch(caller, userID) )
             throw new AccessControlException("permission denied: target user does not match current user");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
@@ -289,7 +289,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
@@ -375,7 +375,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if ( !isMatch(caller, user) )
             throw new AccessControlException("permission denied: target user does not match current user");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
@@ -405,7 +405,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if ( !isMatch(caller, userID) )
             throw new AccessControlException("permission denied: target user does not match current user");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
@@ -489,7 +489,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if ( !isMatch(caller, userID) )
             throw new AccessControlException("permission denied: target user does not match current user");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
@@ -523,14 +523,14 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         Subject caller = AuthenticationUtil.getCurrentSubject();
         if ( !isMatch(caller, userID) )
             throw new AccessControlException("permission denied: target user does not match current user");
-        
+
         LdapUserDAO<T> userDAO = null;
         LdapConnections conns = new LdapConnections(this);
         try
         {
             userDAO = new LdapUserDAO<T>(conns);
             User<T> user = getUser((T) userID);
-            
+
             if (user != null)
             {
                 // oldPassword is correct
@@ -547,7 +547,7 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
     {
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         for (Principal pc : caller.getPrincipals())
         {
             for (Principal pu : user.getIdentities())
@@ -558,12 +558,12 @@ public class LdapUserPersistence<T extends Principal> extends LdapPersistence im
         }
         return false;
     }
-    
+
     private boolean isMatch(Subject caller, Principal userID)
     {
         if (caller == null || AuthMethod.ANON.equals(AuthenticationUtil.getAuthMethod(caller)))
             throw new AccessControlException("Caller is not authenticated");
-        
+
         for (Principal pc : caller.getPrincipals())
         {
             if (AuthenticationUtil.equals(pc, userID))
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ACSearchRunner.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ACSearchRunner.java
index ed53fbd7088208f427bf69163f05987a48950490..8fe2dc7c2dda44e4787b76706f18e6bf94362b55 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ACSearchRunner.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ACSearchRunner.java
@@ -68,6 +68,24 @@
  */
 package ca.nrc.cadc.ac.server.web;
 
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+
 import ca.nrc.cadc.ac.Group;
 import ca.nrc.cadc.ac.GroupNotFoundException;
 import ca.nrc.cadc.ac.UserNotFoundException;
@@ -75,8 +93,6 @@ 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.GroupListWriter;
-import ca.nrc.cadc.auth.AuthenticationUtil;
-import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
 import ca.nrc.cadc.uws.ExecutionPhase;
 import ca.nrc.cadc.uws.Job;
@@ -84,23 +100,6 @@ import ca.nrc.cadc.uws.server.JobRunner;
 import ca.nrc.cadc.uws.server.JobUpdater;
 import ca.nrc.cadc.uws.server.SyncOutput;
 import ca.nrc.cadc.uws.util.JobLogInfo;
-import org.apache.log4j.Logger;
-
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.security.AccessControlContext;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Set;
 
 public class ACSearchRunner implements JobRunner
 {
@@ -221,9 +220,11 @@ public class ACSearchRunner implements JobRunner
 
             syncOut.setResponseCode(503);
             syncOut.setHeader("Content-Type", "text/plain");
+            if (t.getRetryDelay() > 0)
+                syncOut.setHeader("Retry-After", Integer.toString(t.getRetryDelay()));
             try
             {
-                syncOut.getOutputStream().write(t.getMessage().getBytes());
+                syncOut.getOutputStream().write(("Transient Exception: " + t.getMessage()).getBytes());
             }
             catch (IOException e)
             {
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/LoginServlet.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/LoginServlet.java
index 9bada3806a19fc92aedc22320927669f45a5b8b2..e41f01817445947ec685ae08d934590998f29df4 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/LoginServlet.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/LoginServlet.java
@@ -208,6 +208,18 @@ public class LoginServlet<T extends Principal> extends HttpServlet
             response.getWriter().write(message);
             response.setStatus(401);
         }
+        catch (TransientException e)
+        {
+            log.debug(e.getMessage(), e);
+            String message = e.getMessage();
+            logInfo.setMessage(message);
+            logInfo.setSuccess(false);
+            response.setContentType("CONTENT_TYPE");
+            if (e.getRetryDelay() > 0)
+                response.setHeader("Retry-After", Integer.toString(e.getRetryDelay()));
+            response.getWriter().write("Transient Error: " + message);
+            response.setStatus(503);
+        }
         catch (Throwable t)
         {
             String message = "Internal Server Error: " + t.getMessage();
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServlet.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServlet.java
index 4e68b789397db8ca67355366dc37fd537b6d55ba..90d54ebbe421db5bd8d42296e399156601eed8b2 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServlet.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServlet.java
@@ -68,13 +68,11 @@
  */
 package ca.nrc.cadc.ac.server.web;
 
-import ca.nrc.cadc.ac.server.PluginFactory;
-import ca.nrc.cadc.ac.server.UserPersistence;
-import ca.nrc.cadc.auth.AuthenticationUtil;
-import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.log.ServletLogInfo;
-import ca.nrc.cadc.util.StringUtil;
-import org.apache.log4j.Logger;
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Set;
 
 import javax.security.auth.Subject;
 import javax.servlet.ServletConfig;
@@ -82,10 +80,16 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.security.AccessControlException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import ca.nrc.cadc.ac.server.PluginFactory;
+import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.auth.AuthenticationUtil;
+import ca.nrc.cadc.auth.HttpPrincipal;
+import ca.nrc.cadc.log.ServletLogInfo;
+import ca.nrc.cadc.net.TransientException;
+import ca.nrc.cadc.util.StringUtil;
 
 /**
  * Servlet to handle password changes.  Passwords are an integral part of the
@@ -130,8 +134,7 @@ public class ModifyPasswordServlet extends HttpServlet
             logInfo.setSubject(subject);
             if ((subject == null) || (subject.getPrincipals().isEmpty()))
             {
-                logInfo.setMessage("Unauthorized subject");
-                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+                throw new AccessControlException("Unauthorized");
             }
             else
             {
@@ -139,7 +142,7 @@ public class ModifyPasswordServlet extends HttpServlet
                 {
                     public Object run() throws Exception
                     {
-                        
+
                         Set<HttpPrincipal> pset = subject.getPrincipals(HttpPrincipal.class);
                         if (pset.isEmpty())
                             throw new IllegalStateException("no HttpPrincipal in subject");
@@ -167,30 +170,61 @@ public class ModifyPasswordServlet extends HttpServlet
                 });
             }
         }
-        catch (IllegalArgumentException e)
-        {
-            log.debug(e.getMessage(), e);
-            logInfo.setMessage(e.getMessage());
-            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
-        }
-        catch (AccessControlException e)
-        {
-            log.debug(e.getMessage(), e);
-            logInfo.setMessage(e.getMessage());
-            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-        }
         catch (Throwable t)
         {
-            String message = "Internal Server Error: " + t.getMessage();
-            log.error(message, t);
-            logInfo.setSuccess(false);
-            logInfo.setMessage(message);
-            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-        }
-        finally
-        {
-            logInfo.setElapsedTime(System.currentTimeMillis() - start);
-            log.info(logInfo.end());
+            try
+            {
+                if (t instanceof PrivilegedActionException)
+                {
+                    Exception e = ((PrivilegedActionException) t).getException();
+                    if (e != null)
+                    {
+                        throw e;
+                    }
+                }
+
+                throw t;
+            }
+            catch (IllegalArgumentException e)
+            {
+                log.debug(e.getMessage(), e);
+                response.setContentType("text/plain");
+                logInfo.setMessage(e.getMessage());
+                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            }
+            catch (AccessControlException e)
+            {
+                log.debug(e.getMessage(), e);
+                response.setContentType("text/plain");
+                logInfo.setMessage(e.getMessage());
+                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+            }
+            catch (TransientException e)
+            {
+                log.debug(e.getMessage(), e);
+                String message = e.getMessage();
+                logInfo.setMessage(message);
+                logInfo.setSuccess(false);
+                response.setContentType("text/plain");
+                if (e.getRetryDelay() > 0)
+                    response.setHeader("Retry-After", Integer.toString(e.getRetryDelay()));
+                response.getWriter().write("Transient Error: " + message);
+                response.setStatus(503);
+            }
+            catch (Throwable e)
+            {
+                String message = "Internal Server Error: " + e.getMessage();
+                log.error(message, e);
+                response.setContentType("text/plain");
+                logInfo.setSuccess(false);
+                logInfo.setMessage(message);
+                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
+            finally
+            {
+                logInfo.setElapsedTime(System.currentTimeMillis() - start);
+                log.info(logInfo.end());
+            }
         }
     }
 
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ResetPasswordServlet.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ResetPasswordServlet.java
index d3d166e7ea72a890568579eb99a53047bde639e1..8d91304af9065bc4a4aacd4391908055c1ee2a74 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ResetPasswordServlet.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/ResetPasswordServlet.java
@@ -68,29 +68,6 @@
  */
 package ca.nrc.cadc.ac.server.web;
 
-import ca.nrc.cadc.ac.User;
-import ca.nrc.cadc.ac.UserAlreadyExistsException;
-import ca.nrc.cadc.ac.UserNotFoundException;
-import ca.nrc.cadc.ac.server.ACScopeValidator;
-import ca.nrc.cadc.ac.server.PluginFactory;
-import ca.nrc.cadc.ac.server.UserPersistence;
-import ca.nrc.cadc.auth.AuthenticationUtil;
-import ca.nrc.cadc.auth.DelegationToken;
-import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.auth.ServletPrincipalExtractor;
-import ca.nrc.cadc.log.ServletLogInfo;
-import ca.nrc.cadc.util.StringUtil;
-
-import org.apache.log4j.Logger;
-
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import java.io.IOException;
 import java.net.URI;
 import java.security.AccessControlException;
@@ -99,12 +76,35 @@ import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Enumeration;
 import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.Set;
 import java.util.TimeZone;
 
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+
+import ca.nrc.cadc.ac.User;
+import ca.nrc.cadc.ac.UserAlreadyExistsException;
+import ca.nrc.cadc.ac.UserNotFoundException;
+import ca.nrc.cadc.ac.server.ACScopeValidator;
+import ca.nrc.cadc.ac.server.PluginFactory;
+import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.auth.AuthenticationUtil;
+import ca.nrc.cadc.auth.DelegationToken;
+import ca.nrc.cadc.auth.HttpPrincipal;
+import ca.nrc.cadc.auth.ServletPrincipalExtractor;
+import ca.nrc.cadc.log.ServletLogInfo;
+import ca.nrc.cadc.net.TransientException;
+import ca.nrc.cadc.util.StringUtil;
+
 /**
  * Servlet to handle password resets.  Passwords are an integral part of the
  * access control system and are handled differently to accommodate stricter
@@ -144,7 +144,7 @@ public class ResetPasswordServlet extends HttpServlet
                 {
                     throw new RuntimeException("Init exception: Lists of augment subject principals not equivalent in length");
                 }
-    
+
                 privilegedSubjects = new ArrayList<Subject>(x500Users.length());
                 for (int i=0; i<x500List.length; i++)
                 {
@@ -164,14 +164,14 @@ public class ResetPasswordServlet extends HttpServlet
             throw new ExceptionInInitializerError(t);
         }
     }
-    
+
     protected boolean isPrivilegedSubject(final HttpServletRequest request)
-    {        
+    {
         if (privilegedSubjects == null || privilegedSubjects.isEmpty())
         {
             return false;
         }
-        
+
         ServletPrincipalExtractor extractor = new ServletPrincipalExtractor(request);
         Set<Principal> principals = extractor.getPrincipals();
 
@@ -210,7 +210,7 @@ public class ResetPasswordServlet extends HttpServlet
 
         return false;
     }
-    
+
     /**
      * Handle a /ac GET operation. The subject provided is expected to be a privileged user.
      *
@@ -254,7 +254,7 @@ public class ResetPasswordServlet extends HttpServlet
                                 Calendar expiry = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
                                 expiry.add(Calendar.HOUR, duration);
                                 DelegationToken dt = new DelegationToken(userID, scopeURI, expiry.getTime());
-    
+
                                 return DelegationToken.format(dt);
                             }
                             else
@@ -263,7 +263,7 @@ public class ResetPasswordServlet extends HttpServlet
                             }
                         }
                     });
-                    
+
                     response.setContentType("text/plain");
                     response.setContentLength(token.length());
                     response.getWriter().write(token);
@@ -287,7 +287,7 @@ public class ResetPasswordServlet extends HttpServlet
                         throw e;
                     }
                 }
-                
+
                 throw t;
             }
             catch (UserAlreadyExistsException e)
@@ -308,6 +308,18 @@ public class ResetPasswordServlet extends HttpServlet
                 logInfo.setMessage(e.getMessage());
                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
             }
+            catch (TransientException e)
+            {
+                log.debug(e.getMessage(), e);
+                String message = e.getMessage();
+                logInfo.setMessage(message);
+                logInfo.setSuccess(false);
+                response.setContentType("text/plain");
+                if (e.getRetryDelay() > 0)
+                    response.setHeader("Retry-After", Integer.toString(e.getRetryDelay()));
+                response.getWriter().write("Transient Error: " + message);
+                response.setStatus(503);
+            }
             catch (AccessControlException e)
             {
                 log.debug(e.getMessage(), e);
@@ -359,13 +371,13 @@ public class ResetPasswordServlet extends HttpServlet
                 {
                     public Object run() throws Exception
                     {
-                        
+
                         Set<HttpPrincipal> pset = subject.getPrincipals(HttpPrincipal.class);
                         if (pset.isEmpty())
                         {
                             throw new IllegalStateException("no HttpPrincipal in subject");
                         }
-                        
+
                         HttpPrincipal userID = pset.iterator().next();
 
                         String newPassword = request.getParameter("password");
@@ -377,7 +389,7 @@ public class ResetPasswordServlet extends HttpServlet
                         {
                             throw new IllegalArgumentException("Missing password");
                         }
-                        
+
                         return null;
                     }
                 });
@@ -395,7 +407,7 @@ public class ResetPasswordServlet extends HttpServlet
                         throw e;
                     }
                 }
-                
+
                 throw t;
             }
             catch (UserNotFoundException e)
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
index 8a95d1f47ed8bbe71400a8124ba22c7dcba73c95..68ad07dacda36c2a0063ca287685c152445b84f4 100755
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/groups/AbstractGroupAction.java
@@ -68,27 +68,24 @@
  */
 package ca.nrc.cadc.ac.server.web.groups;
 
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.log4j.Logger;
+
 import ca.nrc.cadc.ac.GroupAlreadyExistsException;
 import ca.nrc.cadc.ac.GroupNotFoundException;
 import ca.nrc.cadc.ac.MemberAlreadyExistsException;
 import ca.nrc.cadc.ac.MemberNotFoundException;
 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.UserPersistence;
 import ca.nrc.cadc.ac.server.web.SyncOutput;
 import ca.nrc.cadc.net.TransientException;
-import org.apache.log4j.Logger;
-
-import com.unboundid.ldap.sdk.LDAPException;
-
-import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
-import java.security.AccessControlException;
-import java.security.Principal;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.List;
 
 public abstract class AbstractGroupAction implements PrivilegedExceptionAction<Object>
 {
@@ -187,9 +184,11 @@ public abstract class AbstractGroupAction implements PrivilegedExceptionAction<O
         }
         catch (TransientException e)
         {
-            String message = "Internal Transient Error: " + e.getMessage();
+            String message = "Transient Error: " + e.getMessage();
             this.logInfo.setSuccess(false);
             this.logInfo.setMessage(message);
+            if (e.getRetryDelay() > 0)
+                syncOut.setHeader("Retry-After", Integer.toString(e.getRetryDelay()));
             log.error(message, e);
             sendError(503, message);
         }
diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
index 8888e0007b05bf59fa4dd7ba2c7c1f50e4672da2..09aaa45d453fb3f25bc00d4d3847231de3a7173d 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java
@@ -68,6 +68,16 @@
  */
 package ca.nrc.cadc.ac.server.web.users;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+
 import ca.nrc.cadc.ac.ReaderException;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserAlreadyExistsException;
@@ -86,17 +96,6 @@ import ca.nrc.cadc.ac.xml.UserWriter;
 import ca.nrc.cadc.net.TransientException;
 import ca.nrc.cadc.profiler.Profiler;
 
-import org.apache.log4j.Logger;
-
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.security.AccessControlException;
-import java.security.Principal;
-import java.security.PrivilegedExceptionAction;
-import java.util.Collection;
-
 public abstract class AbstractUserAction<T extends Principal> implements PrivilegedExceptionAction<Object>
 {
     private static final Logger log = Logger.getLogger(AbstractUserAction.class);
@@ -193,9 +192,11 @@ public abstract class AbstractUserAction<T extends Principal> implements Privile
         }
         catch (TransientException e)
         {
-            String message = "Internal Transient Error: " + e.getMessage();
+            String message = "Transient Error: " + e.getMessage();
             this.logInfo.setSuccess(false);
             this.logInfo.setMessage(message);
+            if (e.getRetryDelay() > 0)
+                syncOut.setHeader("Retry-After", Integer.toString(e.getRetryDelay()));
             log.error(message, e);
             sendError(503, message);
         }
diff --git a/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionsTest.java b/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionsTest.java
index 4e473f646341db804e25406643d3eacfd01c7070..fdc511fc63e5552e8a04ad732b9cc5da612d8491 100644
--- a/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionsTest.java
+++ b/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapConnectionsTest.java
@@ -108,7 +108,7 @@ public class LdapConnectionsTest
             EasyMock.expect(persistence.getPool(LdapPersistence.POOL_READONLY)).andReturn(readPool).once();
             EasyMock.expect(persistence.getPool(LdapPersistence.POOL_READWRITE)).andReturn(writePool).once();
             EasyMock.expect(persistence.getPool(LdapPersistence.POOL_UNBOUNDREADONLY)).andReturn(unReadPool).once();
-            EasyMock.expect(persistence.getCurrentConfig()).andReturn(null).once();
+            EasyMock.expect(persistence.getCurrentConfig()).andReturn(null).anyTimes();
 
             EasyMock.expect(readPool.getConnection()).andReturn(readConn).once();
             EasyMock.expect(writePool.getConnection()).andReturn(writeConn).once();
diff --git a/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServletTest.java b/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServletTest.java
index 25ee26f86f4c2fcdf646811c794a4b0e14b1091a..e7c402e2dda7ec15328a1bf0cb40ff5c846e28f0 100644
--- a/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServletTest.java
+++ b/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/ModifyPasswordServletTest.java
@@ -68,11 +68,13 @@
 
 package ca.nrc.cadc.ac.server.web;
 
-import ca.nrc.cadc.ac.server.UserPersistence;
-import ca.nrc.cadc.auth.HttpPrincipal;
-import ca.nrc.cadc.util.StringUtil;
+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 org.junit.Test;
+import java.security.PrivilegedExceptionAction;
 
 import javax.security.auth.Subject;
 import javax.servlet.ServletConfig;
@@ -80,15 +82,24 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import java.security.PrivilegedExceptionAction;
+import org.apache.log4j.Level;
+import org.junit.Test;
 
-import static org.easymock.EasyMock.*;
+import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.auth.HttpPrincipal;
+import ca.nrc.cadc.util.Log4jInit;
+import ca.nrc.cadc.util.StringUtil;
 
 
 public class ModifyPasswordServletTest
 {
-    
-    public void testSubjectAndPasswords(final Subject subject, final String oldPassword, 
+
+    public ModifyPasswordServletTest()
+    {
+        Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO);
+    }
+
+    public void testSubjectAndPasswords(final Subject subject, final String oldPassword,
             final String newPassword, int responseStatus) throws Exception
     {
         @SuppressWarnings("serial")
@@ -100,27 +111,33 @@ public class ModifyPasswordServletTest
                 return subject;
             }
         };
-        
+
         final HttpServletRequest mockRequest =
                 createMock(HttpServletRequest.class);
         final HttpServletResponse mockResponse =
                 createMock(HttpServletResponse.class);
-        
+
         expect(mockRequest.getPathInfo()).andReturn("users/CADCtest").once();
         expect(mockRequest.getMethod()).andReturn("POST").once();
         expect(mockRequest.getRemoteAddr()).andReturn("mysite.com").once();
-        
+
         if (!StringUtil.hasText(oldPassword) || !StringUtil.hasText(newPassword))
         {
             expect(mockRequest.getParameter("old_password")).andReturn(oldPassword).once();
             expect(mockRequest.getParameter("new_password")).andReturn(newPassword).once();
         }
-        
+
+        if (responseStatus != 200)
+        {
+            mockResponse.setContentType("text/plain");
+            expectLastCall().once();
+        }
+
         mockResponse.setStatus(responseStatus);
         expectLastCall().once();
-    
+
         replay(mockRequest, mockResponse);
-    
+
         Subject.doAs(subject, new PrivilegedExceptionAction<Void>()
         {
             @Override
@@ -130,24 +147,24 @@ public class ModifyPasswordServletTest
                 return null;
             }
         });
-    
+
         verify(mockRequest, mockResponse);
     }
-        
+
     @Test
     public void testModifyPasswordWithNullSubject() throws Exception
     {
         final Subject subject = null;
         testSubjectAndPasswords(subject, "oldPass", "newPass", HttpServletResponse.SC_UNAUTHORIZED);
     }
-        
+
     @Test
     public void testModifyPasswordWithEmptySubject() throws Exception
     {
         final Subject subject = new Subject();;
         testSubjectAndPasswords(subject, "oldPass", "newPass", HttpServletResponse.SC_UNAUTHORIZED);
     }
-       
+
     @Test
     public void testModifyPasswordWithMissingOldPassword() throws Exception
     {
@@ -155,7 +172,7 @@ public class ModifyPasswordServletTest
         subject.getPrincipals().add(new HttpPrincipal("CADCtest"));
         testSubjectAndPasswords(subject, "", "newPass", HttpServletResponse.SC_BAD_REQUEST);
     }
-    
+
     @Test
     public void testModifyPasswordWithMissingNewPassword() throws Exception
     {
@@ -163,13 +180,13 @@ public class ModifyPasswordServletTest
         subject.getPrincipals().add(new HttpPrincipal("CADCtest"));
         testSubjectAndPasswords(subject, "oldPass", "", HttpServletResponse.SC_BAD_REQUEST);
     }
-    
+
     public void testModifyPassword(final boolean hasInternalServerError) throws Exception
     {
         final String oldPassword = "oldPass";
         final String newPassword = "newPass";
         HttpPrincipal userID = new HttpPrincipal("CADCtest");
-        
+
         final UserPersistence<?> mockUserPersistence =
                 createMock(UserPersistence.class);
         mockUserPersistence.setPassword(userID, oldPassword, newPassword);
@@ -180,7 +197,7 @@ public class ModifyPasswordServletTest
 
         final Subject subject = new Subject();
         subject.getPrincipals().add(userID);
-    
+
         @SuppressWarnings("serial")
         final ModifyPasswordServlet testSubject = new ModifyPasswordServlet()
         {
@@ -191,33 +208,36 @@ public class ModifyPasswordServletTest
 
                 userPersistence = mockUserPersistence;
             }
-           
+
             @Override
             Subject getSubject(final HttpServletRequest request)
             {
                 return subject;
             }
         };
-        
+
         final HttpServletRequest mockRequest =
                 createMock(HttpServletRequest.class);
         final HttpServletResponse mockResponse =
                 createMock(HttpServletResponse.class);
-        
+
         expect(mockRequest.getPathInfo()).andReturn("users/CADCtest").once();
         expect(mockRequest.getMethod()).andReturn("POST").once();
         expect(mockRequest.getRemoteAddr()).andReturn("mysite.com").once();
         expect(mockRequest.getParameter("old_password")).andReturn(oldPassword).once();
         expect(mockRequest.getParameter("new_password")).andReturn(newPassword).once();
-    
+
         if (hasInternalServerError)
         {
+            mockResponse.setContentType("text/plain");
+            expectLastCall().once();
+
             mockResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             expectLastCall().once();
         }
-    
+
         replay(mockRequest, mockResponse, mockUserPersistence);
-    
+
         Subject.doAs(subject, new PrivilegedExceptionAction<Void>()
         {
             @Override
@@ -228,18 +248,18 @@ public class ModifyPasswordServletTest
                 return null;
             }
         });
-    
+
         verify(mockRequest, mockResponse, mockUserPersistence);
     }
-    
-    
+
+
     @Test
     public void testModifyPasswordWithInternalServerError() throws Exception
     {
         boolean hasInternalServerError = true;
         testModifyPassword(hasInternalServerError);
     }
-    
+
     @Test
     public void testModifyPasswordHappyPath() throws Exception
     {