Index: components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/BasicPoolingRepository.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/BasicPoolingRepository.java	(revision 34030)
+++ components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/BasicPoolingRepository.java	(revision )
@@ -72,7 +72,18 @@
     private MultipleRepository multipleRepository;
     
     private PoolingCounter poolingCounter;
-    
+
+    private final boolean disposePoolWhenEmptyAfterDestroyedObject;
+
+    public BasicPoolingRepository() {
+        disposePoolWhenEmptyAfterDestroyedObject = false;
+    }
+
+    public BasicPoolingRepository(final boolean disposePoolWhenEmptyAfterDestroyedObject) {
+        this.disposePoolWhenEmptyAfterDestroyedObject = disposePoolWhenEmptyAfterDestroyedObject;
+    }
+
+
     public void setLogger(Logger log) {
         this.log = log;
     }
@@ -301,9 +312,8 @@
         if (sessionPool == null || !isActive()) {
             throw new RepositoryException("The session pool of the pooling repository has not been initialized or closed.");
         }
-        
         Session session = null;
-        
+
         try {
             session = (Session) sessionPool.borrowObject();
             
@@ -508,7 +518,9 @@
         doInitialize();
         active = true;
     }
-    
+
+
+
     private void doInitialize() throws RepositoryException {
         if (getRepository() == null && getRepositoryProviderClassName() != null) {
             try {
@@ -1048,6 +1060,17 @@
                         session.logout();
                     }
                 }
+
+                // if the destroy results in a numActive = 0 and numIdle = 0 and the pool repository
+                // is marked to be disposed when empty, we close the entire pool.
+                if (BasicPoolingRepository.this.disposePoolWhenEmptyAfterDestroyedObject) {
+                    if (BasicPoolingRepository.this.sessionPool.getNumActive() + BasicPoolingRepository.this.sessionPool.getNumIdle() == 0) {
+                        log.debug("Disposing disposable pool for '{}'", BasicPoolingRepository.this.defaultCredentialsUserID);
+                        BasicPoolingRepository.this.close();
+                        BasicPoolingRepository.this.multipleRepository.removeRepository(BasicPoolingRepository.this.defaultCredentials);
+                    }
+                }
+
             } catch (Exception e) {
                 if (log.isDebugEnabled()) {
                     log.warn("Failed to log out session.", e);
Index: components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/BasicPoolingRepositoryFactory.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/BasicPoolingRepositoryFactory.java	(revision 33983)
+++ components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/BasicPoolingRepositoryFactory.java	(revision )
@@ -100,9 +100,14 @@
         
         return getObjectInstanceByConfigMap(configMap);
     }
-    
+
     public PoolingRepository getObjectInstanceByConfigMap(Map<String, String> configMap) throws Exception {
-        BasicPoolingRepository poolingRepository = new BasicPoolingRepository();
+        return getObjectInstanceByConfigMap(configMap, false);
+    }
+
+
+    public PoolingRepository getObjectInstanceByConfigMap(Map<String, String> configMap, boolean disposePoolWhenEmptyAfterDestroyedObject) throws Exception {
+        BasicPoolingRepository poolingRepository = new BasicPoolingRepository(disposePoolWhenEmptyAfterDestroyedObject);
         
         for (Map.Entry<String, String> entry : configMap.entrySet()) {
             String type = entry.getKey();
Index: components/session-pool/src/test/java/org/hippoecm/hst/core/jcr/pool/TestLazyMultiplePoolingRepository.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- components/session-pool/src/test/java/org/hippoecm/hst/core/jcr/pool/TestLazyMultiplePoolingRepository.java	(revision 33983)
+++ components/session-pool/src/test/java/org/hippoecm/hst/core/jcr/pool/TestLazyMultiplePoolingRepository.java	(revision )
@@ -160,7 +160,7 @@
     
     @Test
     public void testAutomaticDisposing() throws Exception {
-        ((LazyMultipleRepositoryImpl) multipleRepository).setTimeBetweenEvictionRunsMillis(5000);
+        //((LazyMultipleRepositoryImpl) multipleRepository).setTimeBetweenEvictionRunsMillis(5000);
         ((LazyMultipleRepositoryImpl) multipleRepository).setDisposableUserIDPattern(".*;disposable");
         
         Session session = multipleRepository.login(wikiCreds);
@@ -186,7 +186,7 @@
     
     @Test
     public void testClosingForAutomaticallyDisposedPoolingRepository() throws Exception {
-        ((LazyMultipleRepositoryImpl) multipleRepository).setTimeBetweenEvictionRunsMillis(1000);
+        //((LazyMultipleRepositoryImpl) multipleRepository).setTimeBetweenEvictionRunsMillis(1000);
         ((LazyMultipleRepositoryImpl) multipleRepository).setDisposableUserIDPattern(".*;disposable");
         
         Repository disposableWikiRepo = multipleRepository.getRepositoryByCredentials(disposableWiki2Creds);
Index: components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/LazyMultipleRepositoryImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/LazyMultipleRepositoryImpl.java	(revision 33983)
+++ components/session-pool/src/main/java/org/hippoecm/hst/core/jcr/pool/LazyMultipleRepositoryImpl.java	(revision )
@@ -44,20 +44,22 @@
     private static final Logger log = LoggerFactory.getLogger(LazyMultipleRepositoryImpl.class);
     
     private Map<String, Map<String, PoolingRepository>> repositoriesMapByCredsDomain = Collections.synchronizedMap(new HashMap<String, Map<String, PoolingRepository>>());
-    
+
+
+    private volatile DisposedRepositoryRemover disposedRepositoryRemover;
+    
     private BasicPoolingRepositoryFactory poolingRepositoryFactory;
     private Map<String, String> defaultConfigMap;
     private boolean pooledSessionLifecycleManagementActive = true;
     private String credentialsDomainSeparator = String.valueOf('\uFFFF');
-    
+
-    private long timeBetweenEvictionRunsMillis;
     private Pattern disposableUserIDPatternObject;
-    private InactiveRepositoryDisposer inactiveRepositoryDisposer;
     
     private ResourceLifecycleManagement [] lazyResourceLifecycleManagements;
-    
+
     private ThreadLocal<Set<String>> tlCurrentCredsDomains = new ThreadLocal<Set<String>>();
-    
+
+    
     public LazyMultipleRepositoryImpl(Credentials defaultCredentials, Map<String, String> defaultConfigMap) {
         super(defaultCredentials);
         /*
@@ -91,15 +93,7 @@
     public void setCredentialsDomainSeparator(String credentialsDomainSeparator) {
         this.credentialsDomainSeparator = credentialsDomainSeparator;
     }
-    
+
-    public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
-        if (timeBetweenEvictionRunsMillis < 0) {
-            throw new IllegalArgumentException("timeBetweenEvictionRunsMillis cannot be a negative value.");
-        }
-        
-        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
-    }
-    
     public void setDisposableUserIDPattern(String disposableUserIDPattern) {
         this.disposableUserIDPatternObject = Pattern.compile(disposableUserIDPattern);
     }
@@ -123,52 +117,8 @@
         System.arraycopy(lazyResourceLifecycleManagements, 0, cloned, 0, lazyResourceLifecycleManagements.length);
         return cloned;
     }
-    
+
-    public Map<String, Map<String, PoolingRepository>> cloneRepositoriesMapByCredsDomain() {
-        Map<String, Map<String, PoolingRepository>> clonedRepositoriesMapByCredsDomain = new HashMap<String, Map<String, PoolingRepository>>();
-        
+
-        List<String> credsDomains = new LinkedList<String>();
-        
-        if (repositoriesMapByCredsDomain == null || repositoriesMapByCredsDomain.isEmpty()) {
-            return Collections.emptyMap();
-        }
-        
-        synchronized (repositoriesMapByCredsDomain) {
-            Iterator<String> it = repositoriesMapByCredsDomain.keySet().iterator();
-            while (it.hasNext()) {
-                credsDomains.add(it.next());
-            }
-        }
-        
-        for (String credsDomain : credsDomains) {
-            Map<String, PoolingRepository> repoMap = repositoriesMapByCredsDomain.get(credsDomain);
-            
-            if (repoMap != null && !repoMap.isEmpty()) {
-                List<String> userIDs = new LinkedList<String>();
-                
-                synchronized (repoMap) {
-                    Iterator<String> it = repoMap.keySet().iterator();
-                    while (it.hasNext()) {
-                        userIDs.add(it.next());
-                    }
-                }
-                
-                Map<String, PoolingRepository> clonedRepoMap = new HashMap<String, PoolingRepository>();
-                
-                for (String userID : userIDs) {
-                    PoolingRepository repo = repoMap.get(userID);
-                    if (repo != null) {
-                        clonedRepoMap.put(userID, repo);
-                    }
-                }
-                
-                clonedRepositoriesMapByCredsDomain.put(credsDomain, clonedRepoMap);
-            }
-        }
-        
-        return clonedRepositoriesMapByCredsDomain;
-    }
-    
     @Override
     protected Session login(CredentialsWrapper credentialsWrapper) throws LoginException, RepositoryException {
         Repository repository = repositoryMap.get(credentialsWrapper);
@@ -211,9 +161,12 @@
         if (poolingRepositoryFactory == null) {
             poolingRepositoryFactory = new BasicPoolingRepositoryFactory();
         }
-        
+
+        if (disposableUserIDPatternObject != null && disposableUserIDPatternObject.matcher(userID).matches()) {
+            repository = poolingRepositoryFactory.getObjectInstanceByConfigMap(configMap, true);
+        } else {
-        repository = poolingRepositoryFactory.getObjectInstanceByConfigMap(configMap);
+            repository = poolingRepositoryFactory.getObjectInstanceByConfigMap(configMap);
-        
+        }
         if (repository instanceof MultipleRepositoryAware) {
             ((MultipleRepositoryAware) repository).setMultipleRepository(this);
         }
@@ -226,21 +179,22 @@
 
         String credentialsDomain = StringUtils.substringAfter(userID, credentialsDomainSeparator);
         Map<String, PoolingRepository> credsDomainRepos = repositoriesMapByCredsDomain.get(credentialsDomain);
-        
+
+        System.out.println(credentialsDomain);
         if (credsDomainRepos == null) {
             credsDomainRepos = Collections.synchronizedMap(new HashMap<String, PoolingRepository>());
         }
-        
+
         credsDomainRepos.put(userID, repository);
-        
+
         repositoriesMapByCredsDomain.put(credentialsDomain, credsDomainRepos);
         
         lazyResourceLifecycleManagements = null;
         repositoryMap.put(credentialsWrapper, repository);
-        
+
-        if (timeBetweenEvictionRunsMillis > 0L && inactiveRepositoryDisposer == null) {
-            inactiveRepositoryDisposer = new InactiveRepositoryDisposer();
-            inactiveRepositoryDisposer.start();
+        if (disposedRepositoryRemover == null) {
+            disposedRepositoryRemover = new DisposedRepositoryRemover();
+            disposedRepositoryRemover.start();
         }
         
         return repository;
@@ -311,20 +265,20 @@
             
             return null;
         }
-        
+
         private ResourceLifecycleManagement getResourceLifecycleManagementBySession(PooledSession session) {
             String userID = session.getUserID();
             String credsDomain = StringUtils.substringAfter(userID, credentialsDomainSeparator);
             Map<String, PoolingRepository> repoMap = repositoriesMapByCredsDomain.get(credsDomain);
-            
+
             if (repoMap != null) {
                 PoolingRepository repository = repoMap.get(userID);
-                
+
                 if (repository != null) {
                     return repository.getResourceLifecycleManagement();
                 }
             }
-            
+
             return null;
         }
         
@@ -340,7 +294,6 @@
                     if (repoMap == null) {
                         continue;
                     }
-                    
                     synchronized (repoMap) {
                         for (PoolingRepository repository : repoMap.values()) {
                             ResourceLifecycleManagement resourceLifecycleManagement = repository.getResourceLifecycleManagement();
@@ -356,90 +309,72 @@
             return resourceLifecycleManagements;
         }
     }
-    
+
-    private class InactiveRepositoryDisposer extends Thread {
+    private class DisposedRepositoryRemover extends Thread {
-        
+
         private boolean stopped;
-        
+
-        private InactiveRepositoryDisposer() {
+        private DisposedRepositoryRemover() {
             super("InactiveRepositoryDisposer");
             setDaemon(true);
         }
         
         public void run() {
-            
+
             boolean interrupted = stopped;
-            
+
             synchronized (this) {
                 try {
-                    wait(timeBetweenEvictionRunsMillis);
+                    wait(10000);
                 } catch (InterruptedException e) {
                     interrupted = true;
                 }
             }
-            
+
             stopped = interrupted;
-            
+
             while (!stopped) {
-                Map<String, Map<String, PoolingRepository>> clonedRepositoriesMapByCredsDomain = cloneRepositoriesMapByCredsDomain();
-                
+
-                for (Map.Entry<String, Map<String, PoolingRepository>> entry1 : clonedRepositoriesMapByCredsDomain.entrySet()) {
+                synchronized (LazyMultipleRepositoryImpl.this) {
+                   
+                Set<String> credsDomainsToBeRemoved = new HashSet<String>();
+
+                    for (Map.Entry<String, Map<String, PoolingRepository>> entry1 : repositoriesMapByCredsDomain.entrySet()) {
-                    String credsDomain = entry1.getKey();
+                        String credsDomain = entry1.getKey();
-                    Map<String, PoolingRepository> clonedRepoMap = entry1.getValue();
-                    
+                        
-                    for (Map.Entry<String, PoolingRepository> entry2: clonedRepoMap.entrySet()) {
+                        for (Map.Entry<String, PoolingRepository> entry2: entry1.getValue().entrySet()) {
-                        String userID = entry2.getKey();
-                        
-                        if (disposableUserIDPatternObject != null && !disposableUserIDPatternObject.matcher(userID).matches()) {
-                            continue;
-                        }
-                        
-                        PoolingRepository poolingRepo = entry2.getValue();
+                            String userID = entry2.getKey();
+    
+                            if (disposableUserIDPatternObject != null && !disposableUserIDPatternObject.matcher(userID).matches()) {
+                                continue;
+                            }
+    
+                            PoolingRepository poolingRepo = entry2.getValue();
-                        
-                        if (poolingRepo.getNumIdle() <= 0 && poolingRepo.getNumActive() <= 0) {
-                            synchronized (LazyMultipleRepositoryImpl.this) {
-                                if (poolingRepo.getNumIdle() <= 0 && poolingRepo.getNumActive() <= 0) {
-                                    Map<String, PoolingRepository> repoMap = repositoriesMapByCredsDomain.get(credsDomain);
-                                    
-                                    if (repoMap != null) {
-                                        PoolingRepository removed = repoMap.remove(userID);
-                                        
-                                        if (removed != null) {
-                                            try {
-                                                removeRepository(((BasicPoolingRepository) removed).getDefaultCredentials());
-                                                removed.close();
-                                            } catch (Exception e) {
-                                                if (log.isDebugEnabled()) {
-                                                    log.warn("Failed to close an inactive pooling repository.", e);
-                                                } else {
-                                                    log.warn("Failed to close an inactive pooling repository. {}", e.toString());
+                            if (!poolingRepo.isActive()) {
+                                credsDomainsToBeRemoved.add(credsDomain);
-                                                }
-                                            }
-                                            
+                            }
+                        }
+                        
-                                            if (repoMap.isEmpty()) {
-                                                Map<String, PoolingRepository> removedMap = repositoriesMapByCredsDomain.remove(credsDomain);
-                                            }
+                    }
+                    for (String remove : credsDomainsToBeRemoved) {
+                         repositoriesMapByCredsDomain.remove(remove);
-                                        }
-                                    }
+                    }
+                }
-                                }
-                            }
-                        }
-                    }
-                }
-                
+
                 synchronized (this) {
                     try {
-                        wait(timeBetweenEvictionRunsMillis);
+                        wait(10000);
                     } catch (InterruptedException e) {
                         interrupted = true;
                         break;
                     }
                 }
-                
+
                 stopped = interrupted;
             }
         }
     }
+    
     
     private Map<String, String> trimWhiteSpaceValues(Map<String, String> configMap) {
         if (configMap == null) {
Index: components/core/src/main/resources/org/hippoecm/hst/site/container/SpringComponentManager-jcr.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- components/core/src/main/resources/org/hippoecm/hst/site/container/SpringComponentManager-jcr.xml	(revision 33983)
+++ components/core/src/main/resources/org/hippoecm/hst/site/container/SpringComponentManager-jcr.xml	(revision )
@@ -227,10 +227,7 @@
         <entry key="maxRefreshIntervalOnPassivate" value="${disposable.repository.maxRefreshIntervalOnPassivate}"/>
       </map>
     </constructor-arg>
-    
+
-    <!-- This is the interval for evicting disposable session pools when all its sessions are evicted -->
-    <property name="timeBetweenEvictionRunsMillis" value="${disposable.global.repository.timeBetweenEvictionRunsMillis}"/>
-    
     <property name="disposableUserIDPattern" value=".*;disposable"/>
     <property name="credentialsDomainSeparator" value="${repository.pool.user.name.separator}"/>
   </bean>
