Index: src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java	(revision 1148512)
+++ src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java	(working copy)
@@ -33,6 +33,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Credentials;
@@ -71,6 +73,7 @@
 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
 import org.apache.commons.httpclient.methods.RequestEntity;
 import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
 import org.apache.jackrabbit.commons.webdav.EventUtil;
 import org.apache.jackrabbit.commons.webdav.JcrRemotingConstants;
 import org.apache.jackrabbit.commons.webdav.JcrValueType;
@@ -203,7 +206,11 @@
 // TODO: TO-BE-FIXED. caches don't get adjusted upon removal/move of items
 public class RepositoryServiceImpl implements RepositoryService, DavConstants {
 
-    private static Logger log = LoggerFactory.getLogger(RepositoryServiceImpl.class);
+	public static final int MAX_HTTP_CONNECTIONS_DEFAULT = 20;
+    private static final int CLIENTS_CACHE_CONCURRENCY_LEVEL_DEFAULT = MAX_HTTP_CONNECTIONS_DEFAULT;
+	private static final int CLIENTS_CACHE_INITIAL_CAPACITY_DEFAULT = MAX_HTTP_CONNECTIONS_DEFAULT;
+	
+	private static Logger log = LoggerFactory.getLogger(RepositoryServiceImpl.class);
 
     private static final SubscriptionInfo S_INFO = new SubscriptionInfo(DefaultEventType.create(EventUtil.EVENT_ALL, ItemResourceConstants.NAMESPACE), true, INFINITE_TIMEOUT);
 
@@ -220,7 +227,14 @@
     private final URIResolverImpl uriResolver;
 
     private final HostConfiguration hostConfig;
-    private final Map<SessionInfo, HttpClient> clients = new HashMap<SessionInfo, HttpClient>();
+    private final ConcurrentMap<Object, HttpClient> clients;
+   
+    /* Previously, the null SessionInfo was used for the key on the remoting calls made during the 
+     * instantiation of the Repository itself.   Perhaps we could make a dummy version of SessionInfo if
+     * we want to keep the generic typing the same here.  But I don't really see any reason.  
+     * */
+    private static final String CLIENT_KEY_FOR_REPO_CREATION = "repoCreation"; 
+    
     private final HttpConnectionManager connectionManager;
 
     private final Map<Name, QNodeTypeDefinition> nodeTypeDefinitions = new HashMap<Name, QNodeTypeDefinition>();
@@ -234,12 +248,20 @@
 
         this(uri, idFactory, nameFactory, pathFactory, qValueFactory, ItemInfoCacheImpl.DEFAULT_CACHE_SIZE);
     }
+    
+    public RepositoryServiceImpl(String uri, IdFactory idFactory,
+            NameFactory nameFactory,
+            PathFactory pathFactory,
+            QValueFactory qValueFactory, int itemInfoCacheSize) throws RepositoryException {
 
+        this(uri, idFactory, nameFactory, pathFactory, qValueFactory, itemInfoCacheSize, -1);
+    }
+    
     public RepositoryServiceImpl(String uri, IdFactory idFactory,
                                  NameFactory nameFactory,
                                  PathFactory pathFactory,
                                  QValueFactory qValueFactory,
-                                 int itemInfoCacheSize) throws RepositoryException {
+                                 int itemInfoCacheSize, int maximumHttpConnections ) throws RepositoryException {
         if (uri == null || "".equals(uri)) {
             throw new RepositoryException("Invalid repository uri '" + uri + "'.");
         }
@@ -272,7 +294,23 @@
         } catch (URIException e) {
             throw new RepositoryException(e);
         }
+        
         connectionManager = new MultiThreadedHttpConnectionManager();
+        if ( maximumHttpConnections > 0 ) {
+    	  HttpConnectionManagerParams connectionParams = connectionManager.getParams();
+          connectionParams.setDefaultMaxConnectionsPerHost(maximumHttpConnections);  
+          connectionParams.setMaxTotalConnections(maximumHttpConnections);
+          
+          //This configuration of the clients cache assumes that the level of concurrency on this map will be equal to 
+          //the number of maximum connections allowed on the httpClient level.  This could be wrong, but as I understand it
+          //that is the limit on the number of threads that may be intteracting with this map.  
+          clients = new ConcurrentHashMap<Object, HttpClient>(maximumHttpConnections, .75f, maximumHttpConnections);
+
+        } else {
+          clients = new ConcurrentHashMap<Object, HttpClient>(CLIENTS_CACHE_INITIAL_CAPACITY_DEFAULT, .75f, CLIENTS_CACHE_CONCURRENCY_LEVEL_DEFAULT);
+        }
+        
+        
     }
 
     private static void checkSessionInfo(SessionInfo sessionInfo) throws RepositoryException {
@@ -366,7 +404,11 @@
     }
 
     protected HttpClient getClient(SessionInfo sessionInfo) throws RepositoryException {
-        HttpClient client = clients.get(sessionInfo);
+    	
+    	Object clientKey = getClientKey(sessionInfo);	
+    	
+   		HttpClient client = clients.get(clientKey);
+	
         if (client == null) {
             client = new HttpClient(connectionManager);
             client.setHostConfiguration(hostConfig);
@@ -380,14 +422,42 @@
                 client.getParams().setAuthenticationPreemptive(true);
             }
             client.getState().setCredentials(AuthScope.ANY, creds);
-            clients.put(sessionInfo, client);
+            clients.put(clientKey, client);
             log.debug("Created Client " + client + " for SessionInfo " + sessionInfo);
         }
         return client;
     }
 
+    /**
+     * Returns a key for the httpClient hash.  The key is either the SessionInfo object for the session,
+     * or if there is not session, as in the case of the repository instantiation sequence, we have to use 
+     * a separate object.  
+     * <p>
+     * TODO Are there other situations that don't have a sessionInfo?  I'm assuming there's just the one, which could be wrong.
+     * 
+     * @param sessionInfo
+     * @return
+     */
+	private Object getClientKey(SessionInfo sessionInfo) {
+		Object clientKey = null;
+    	if ( sessionInfo == null ) {
+    		clientKey = CLIENT_KEY_FOR_REPO_CREATION;
+    	}
+    	else {
+    		clientKey = sessionInfo;
+    	}
+		return clientKey;
+	}
+
     private void removeClient(SessionInfo sessionInfo) {
-        HttpClient cl = clients.remove(sessionInfo);
+    	HttpClient cl = null;
+    	
+    	if ( sessionInfo == null ) {
+            cl = clients.remove(CLIENT_KEY_FOR_REPO_CREATION);
+    	} else {
+            cl = clients.remove(sessionInfo);
+    	}
+    	
         log.debug("Removed Client " + cl + " for SessionInfo " + sessionInfo);
     }
 
