diff --git a/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java b/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
new file mode 100644
index 0000000..57d0907
--- /dev/null
+++ b/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
@@ -0,0 +1,389 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.gcloud.session;
+
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.server.session.AbstractSessionDataStore;
+import org.eclipse.jetty.server.session.SessionContext;
+import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+import com.google.gcloud.datastore.Blob;
+import com.google.gcloud.datastore.Datastore;
+import com.google.gcloud.datastore.DatastoreFactory;
+import com.google.gcloud.datastore.Entity;
+import com.google.gcloud.datastore.Key;
+import com.google.gcloud.datastore.KeyFactory;
+import com.google.gcloud.datastore.ProjectionEntity;
+import com.google.gcloud.datastore.Query;
+import com.google.gcloud.datastore.QueryResults;
+import com.google.gcloud.datastore.StructuredQuery;
+import com.google.gcloud.datastore.StructuredQuery.CompositeFilter;
+import com.google.gcloud.datastore.StructuredQuery.KeyQueryBuilder;
+import com.google.gcloud.datastore.StructuredQuery.Projection;
+import com.google.gcloud.datastore.StructuredQuery.ProjectionEntityQueryBuilder;
+import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
+
+/**
+ * GCloudSessionDataStore
+ *
+ *
+ */
+public class GCloudSessionDataStore extends AbstractSessionDataStore
+{
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+
+    public  static final String ID = "id";
+    public  static final String CONTEXTPATH = "contextPath";
+    public  static final String VHOST = "vhost";
+    public  static final String ACCESSED = "accessed";
+    public  static final String LASTACCESSED = "lastAccessed";
+    public  static final String CREATETIME = "createTime";
+    public  static final  String COOKIESETTIME = "cookieSetTime";
+    public  static final String LASTNODE = "lastNode";
+    public  static final String EXPIRY = "expiry";
+    public  static final  String MAXINACTIVE = "maxInactive";
+    public  static final  String ATTRIBUTES = "attributes";
+
+    public static final String KIND = "GCloudSession";
+    public static final int DEFAULT_MAX_QUERY_RESULTS = 100;
+
+    private GCloudConfiguration _config;
+    private Datastore _datastore;
+    private KeyFactory _keyFactory;
+    private int _maxResults = DEFAULT_MAX_QUERY_RESULTS;
+    
+
+    
+    
+    
+    
+    
+    
+    
+    
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        
+        if (_config == null)
+            throw new IllegalStateException("No DataStore configuration");
+        
+        _datastore = DatastoreFactory.instance().get(_config.getDatastoreOptions());
+        _keyFactory = _datastore.newKeyFactory().kind(KIND);
+        
+        super.doStart();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+    }
+    
+    
+    /**
+     * @param cfg
+     */
+    public void setGCloudConfiguration (GCloudConfiguration cfg)
+    {
+        _config = cfg;
+    }
+    
+    /**
+     * @return
+     */
+    public GCloudConfiguration getGCloudConfiguration ()
+    {
+        return _config;
+    }
+
+    
+    /**
+     * @return
+     */
+    public int getMaxResults()
+    {
+        return _maxResults;
+    }
+
+
+    /**
+     * @param maxResults
+     */
+    public void setMaxResults(int maxResults)
+    {
+        if (_maxResults <= 0)
+            _maxResults = DEFAULT_MAX_QUERY_RESULTS;
+        else
+            _maxResults = maxResults;
+    }
+    
+    
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {
+        if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from DataStore", id);
+
+        Entity entity = _datastore.get(makeKey(id, _context));
+        if (entity == null)
+        {
+            if (LOG.isDebugEnabled()) LOG.debug("No session {} in DataStore ", id);
+            return null;
+        }
+        else
+        {
+            SessionData data = sessionFromEntity(entity);
+            return data;
+        }
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {
+        if (LOG.isDebugEnabled()) LOG.debug("Removing session {} from DataStore", id);
+        _datastore.delete(makeKey(id, _context));
+        return true;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+       long now = System.currentTimeMillis();
+       Set<String> expired = new HashSet<String>();
+        
+       //get up to maxResult number of sessions that have expired
+       ProjectionEntityQueryBuilder pbuilder = Query.projectionEntityQueryBuilder();
+       pbuilder.addProjection(Projection.property(ID));
+       pbuilder.filter(CompositeFilter.and(PropertyFilter.gt(EXPIRY, 0), PropertyFilter.le(EXPIRY, now)));
+       pbuilder.limit(_maxResults);
+       pbuilder.kind(KIND);
+       StructuredQuery<ProjectionEntity> pquery = pbuilder.build();
+       QueryResults<ProjectionEntity> presults = _datastore.run(pquery);
+       
+       while (presults.hasNext())
+       {
+           ProjectionEntity pe = presults.next();
+           String id = pe.getString(ID);
+           expired.add(id);
+       }
+      
+       //reconcile against ids that the SessionStore thinks are expired
+       Set<String> tmp = new HashSet<String>(candidates);
+       tmp.removeAll(expired);       
+       if (!tmp.isEmpty())
+       {
+           //sessionstore thinks these are expired, but they are either no
+           //longer in the db or not expired in the db, or we exceeded the
+           //number of records retrieved by the expiry query, so check them
+           //individually
+           for (String s:tmp)
+           {
+               try
+               {
+                   KeyQueryBuilder kbuilder = Query.keyQueryBuilder();
+                   kbuilder.filter(PropertyFilter.eq(ID, s));
+                   kbuilder.kind(KIND);
+                   StructuredQuery<Key> kq = kbuilder.build();
+                   QueryResults<Key> kresults = _datastore.run(kq);
+                   if (!kresults.hasNext())
+                       expired.add(s); //not in db, can be expired
+               }
+               catch (Exception e)
+               {
+                   LOG.warn(e);
+               }
+           }
+       }
+       
+       return expired;
+        
+    }
+
+ 
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, boolean)
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        if (LOG.isDebugEnabled()) LOG.debug("Writing session {} to DataStore", data.getId());
+    
+        Entity entity = entityFromSession(data, makeKey(id, _context));
+        _datastore.put(entity);
+    }
+
+    /**
+     * Make a unique key for this session.
+     * As the same session id can be used across multiple contexts, to
+     * make it unique, the key must be composed of:
+     * <ol>
+     * <li>the id</li>
+     * <li>the context path</li>
+     * <li>the virtual hosts</li>
+     * </ol>
+     * 
+     *
+     * @param session
+     * @return
+     */
+    private Key makeKey (String id, SessionContext context)
+    {
+        String key = context.getCanonicalContextPath()+"_"+context.getVhost()+"_"+id;
+        return _keyFactory.newKey(key);
+    }
+    
+    
+    /**
+     * Generate a gcloud datastore Entity from SessionData
+     * @param session
+     * @param key
+     * @return
+     * @throws Exception
+     */
+    private Entity entityFromSession (SessionData session, Key key) throws Exception
+    {
+        if (session == null)
+            return null;
+        
+        Entity entity = null;
+        
+        //serialize the attribute map
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(session.getAllAttributes());
+        oos.flush();
+        
+        //turn a session into an entity
+        entity = Entity.builder(key)
+                .set(ID, session.getId())
+                .set(CONTEXTPATH, session.getContextPath())
+                .set(VHOST, session.getVhost())
+                .set(ACCESSED, session.getAccessed())
+                .set(LASTACCESSED, session.getLastAccessed())
+                .set(CREATETIME, session.getCreated())
+                .set(COOKIESETTIME, session.getCookieSet())
+                .set(LASTNODE,session.getLastNode())
+                .set(EXPIRY, session.getExpiry())
+                .set(MAXINACTIVE, session.getMaxInactiveMs())
+                .set(ATTRIBUTES, Blob.copyFrom(baos.toByteArray())).build();
+                 
+        return entity;
+    }
+    
+    /**
+     * Generate SessionData from an Entity retrieved from gcloud datastore.
+     * @param entity
+     * @return
+     * @throws Exception
+     */
+    private SessionData sessionFromEntity (Entity entity) throws Exception
+    {
+        if (entity == null)
+            return null;
+
+        final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        Runnable load = new Runnable()
+        {
+            public void run ()
+            {
+                try
+                {
+                    //turn an Entity into a Session
+                    String id = entity.getString(ID);
+                    String contextPath = entity.getString(CONTEXTPATH);
+                    String vhost = entity.getString(VHOST);
+                    long accessed = entity.getLong(ACCESSED);
+                    long lastAccessed = entity.getLong(LASTACCESSED);
+                    long createTime = entity.getLong(CREATETIME);
+                    long cookieSet = entity.getLong(COOKIESETTIME);
+                    String lastNode = entity.getString(LASTNODE);
+                    long expiry = entity.getLong(EXPIRY);
+                    long maxInactive = entity.getLong(MAXINACTIVE);
+                    Blob blob = (Blob) entity.getBlob(ATTRIBUTES);
+
+                    SessionData session = newSessionData (id, createTime, accessed, lastAccessed, maxInactive);
+                    session.setLastNode(lastNode);
+                    session.setContextPath(contextPath);
+                    session.setVhost(vhost);
+                    session.setCookieSet(cookieSet);
+                    session.setLastNode(lastNode);
+                    session.setExpiry(expiry);
+                    try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
+                    {
+                        Object o = ois.readObject();
+                        session.putAllAttributes((Map<String,Object>)o);
+                    }
+                    reference.set(session);
+                }
+                catch (Exception e)
+                {
+                    exception.set(e);
+                }
+            }
+        };
+        
+        //ensure this runs in the context classloader
+       _context.run(load);
+    
+        if (exception.get() != null)
+            throw exception.get();
+        
+        return reference.get();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+     */
+    @Override
+    public boolean isPassivating()
+    {
+       return true;
+    }
+    
+    
+}
diff --git a/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java b/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java
index e8a32a5..3a38f52 100644
--- a/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java
+++ b/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java
@@ -20,16 +20,9 @@
 
 import java.util.Random;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.session.AbstractSession;
 import org.eclipse.jetty.server.session.AbstractSessionIdManager;
-import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 
@@ -52,7 +45,6 @@
     private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
     public static final int DEFAULT_IDLE_EXPIRY_MULTIPLE = 2;
     public static final String KIND = "GCloudSessionId";
-    private Server _server;
     private Datastore _datastore;
     private KeyFactory _keyFactory;
     private GCloudConfiguration _config;
@@ -65,8 +57,7 @@
      */
     public GCloudSessionIdManager(Server server)
     {
-        super();
-        _server = server;
+        super(server);
     }
 
     /**
@@ -75,8 +66,7 @@
      */
     public GCloudSessionIdManager(Server server, Random random)
     {
-       super(random);
-       _server = server;
+       super(server,random);
     }
 
 
@@ -111,56 +101,7 @@
     }
 
     
-   
-
-    
-    /** 
-     * Check to see if the given session id is being
-     * used by a session in any context.
-     * 
-     * This method will consult the cluster.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#idInUse(java.lang.String)
-     */
-    @Override
-    public boolean idInUse(String id)
-    {
-        if (id == null)
-            return false;
-        
-        String clusterId = getClusterId(id);
-        
-        //ask the cluster - this should also tickle the idle expiration timer on the sessionid entry
-        //keeping it valid
-        try
-        {
-            return exists(clusterId);
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Problem checking inUse for id="+clusterId, e);
-            return false;
-        }
-        
-    }
-
-    /** 
-     * Remember a new in-use session id.
-     * 
-     * This will save the in-use session id to the cluster.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
-     */
-    @Override
-    public void addSession(HttpSession session)
-    {
-        if (session == null)
-            return;
-
-        //insert into the store
-        insert (((AbstractSession)session).getClusterId());
-    }
-
+ 
   
 
     
@@ -174,91 +115,8 @@
         _config = config;
     }
 
-    
-    
-    /** 
-     * Remove a session id from the list of in-use ids.
-     * 
-     * This will remvove the corresponding session id from the cluster.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
-     */
-    @Override
-    public void removeSession(HttpSession session)
-    {
-        if (session == null)
-            return;
+   
 
-        //delete from the cache
-        delete (((AbstractSession)session).getClusterId());
-    }
-
-    /** 
-     * Remove a session id. This compels all other contexts who have a session
-     * with the same id to also remove it.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
-     */
-    @Override
-    public void invalidateAll(String id)
-    {
-        //delete the session id from list of in-use sessions
-        delete (id);
-
-
-        //tell all contexts that may have a session object with this id to
-        //get rid of them
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null)
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof GCloudSessionManager)
-                {
-                    ((GCloudSessionManager)manager).invalidateSession(id);
-                }
-            }
-        }
-
-    }
-
-    /** 
-     * Change a session id. 
-     * 
-     * Typically this occurs when a previously existing session has passed through authentication.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
-     */
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
-    {
-        //generate a new id
-        String newClusterId = newSessionId(request.hashCode());
-
-        delete(oldClusterId);
-        insert(newClusterId);
-
-
-        //tell all contexts to update the id 
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null) 
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof GCloudSessionManager)
-                {
-                    ((GCloudSessionManager)manager).renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
-                }
-            }
-        }
-
-    }
 
     
     
@@ -300,12 +158,13 @@
      * 
      * @param id
      */
-    protected void delete (String id)
+    protected boolean delete (String id)
     {
         if (_datastore == null)
             throw new IllegalStateException ("No DataStore");
         
         _datastore.delete(makeKey(id));
+        return true; //gcloud does not distinguish between first and subsequent removes
     }
     
     
@@ -320,4 +179,53 @@
     {
         return _keyFactory.newKey(id);
     }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
+     */
+    @Override
+    public boolean isIdInUse(String id)
+    {
+        if (id == null)
+            return false;
+        
+        
+        //ask the cluster - this should also tickle the idle expiration timer on the sessionid entry
+        //keeping it valid
+        try
+        {
+            return exists(id);
+        }
+        catch (Exception e)
+        {
+            LOG.warn("Problem checking inUse for id="+id, e);
+            return false;
+        }
+        
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#useId(org.eclipse.jetty.server.session.Session)
+     */
+    @Override
+    public void useId(Session session)
+    {
+        if (session == null)
+            return;
+
+        //insert into the store
+        insert (session.getId());
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
+     */
+    @Override
+    public boolean removeId(String id)
+    {
+       if (id == null)
+           return false;
+       
+       return delete(id);
+    }
 }
diff --git a/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java b/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java
index a6137e4..42ed761 100644
--- a/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java
+++ b/jetty-gcloud/gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java
@@ -18,43 +18,16 @@
 
 package org.eclipse.jetty.gcloud.session;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReentrantLock;
 
 import javax.servlet.http.HttpServletRequest;
 
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.handler.ContextHandler.Context;
-import org.eclipse.jetty.server.session.AbstractSession;
-import org.eclipse.jetty.server.session.AbstractSessionManager;
-import org.eclipse.jetty.server.session.MemSession;
-import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+import org.eclipse.jetty.server.session.AbstractSessionStore;
+import org.eclipse.jetty.server.session.MemorySessionStore;
+import org.eclipse.jetty.server.session.SessionManager;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
-
-import com.google.gcloud.datastore.Blob;
-import com.google.gcloud.datastore.Datastore;
-import com.google.gcloud.datastore.DatastoreFactory;
-import com.google.gcloud.datastore.Entity;
-import com.google.gcloud.datastore.GqlQuery;
-import com.google.gcloud.datastore.Key;
-import com.google.gcloud.datastore.KeyFactory;
-import com.google.gcloud.datastore.Query;
-import com.google.gcloud.datastore.Query.ResultType;
-import com.google.gcloud.datastore.QueryResults;
 
 
 
@@ -63,360 +36,50 @@
  * 
  * 
  */
-public class GCloudSessionManager extends AbstractSessionManager
+public class GCloudSessionManager extends SessionManager
 {
     private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
-    
-    
-    public static final String KIND = "GCloudSession";
-    public static final int DEFAULT_MAX_QUERY_RESULTS = 100;
-    public static final long DEFAULT_SCAVENGE_SEC = 600; 
-    
-    /**
-     * Sessions known to this node held in memory
-     */
-    private ConcurrentHashMap<String, GCloudSessionManager.Session> _sessions;
+
+  
+ 
+
+
+    private GCloudSessionDataStore _sessionDataStore = null;
+
+
 
     
-    /**
-     * The length of time a session can be in memory without being checked against
-     * the cluster. A value of 0 indicates that the session is never checked against
-     * the cluster - the current node is considered to be the master for the session.
-     *
-     */
-    private long _staleIntervalSec = 0;
+/*
     
-    protected Scheduler.Task _task; //scavenge task
-    protected Scheduler _scheduler;
-    protected Scavenger _scavenger;
-    protected long _scavengeIntervalMs = 1000L * DEFAULT_SCAVENGE_SEC; //10mins
-    protected boolean _ownScheduler;
-    
-    private Datastore _datastore;
-    private KeyFactory _keyFactory;
-
-
-    private SessionEntityConverter _converter;
-
-
-    private int _maxResults = DEFAULT_MAX_QUERY_RESULTS;
-
-
-    /**
-     * Scavenger
-     *
-     */
-    protected class Scavenger implements Runnable
-    {
-
-        @Override
-        public void run()
-        {
-           try
-           {
-               scavenge();
-           }
-           finally
-           {
-               if (_scheduler != null && _scheduler.isRunning())
-                   _task = _scheduler.schedule(this, _scavengeIntervalMs, TimeUnit.MILLISECONDS);
-           }
-        }
-    }
-
-    /**
-     * SessionEntityConverter
-     *
-     *
-     */
-    public class SessionEntityConverter
-    {
-        public  final String CLUSTERID = "clusterId";
-        public  final String CONTEXTPATH = "contextPath";
-        public  final String VHOST = "vhost";
-        public  final String ACCESSED = "accessed";
-        public  final String LASTACCESSED = "lastAccessed";
-        public  final String CREATETIME = "createTime";
-        public  final  String COOKIESETTIME = "cookieSetTime";
-        public  final String LASTNODE = "lastNode";
-        public  final String EXPIRY = "expiry";
-        public  final  String MAXINACTIVE = "maxInactive";
-        public  final  String ATTRIBUTES = "attributes";
-
-      
-        
-        public Entity entityFromSession (Session session, Key key) throws Exception
-        {
-            if (session == null)
-                return null;
-            
-            Entity entity = null;
-            
-            //serialize the attribute map
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(session.getAttributeMap());
-            oos.flush();
-            
-            //turn a session into an entity
-            entity = Entity.builder(key)
-                    .set(CLUSTERID, session.getId())
-                    .set(CONTEXTPATH, session.getContextPath())
-                    .set(VHOST, session.getVHost())
-                    .set(ACCESSED, session.getAccessed())
-                    .set(LASTACCESSED, session.getLastAccessedTime())
-                    .set(CREATETIME, session.getCreationTime())
-                    .set(COOKIESETTIME, session.getCookieSetTime())
-                    .set(LASTNODE,session.getLastNode())
-                    .set(EXPIRY, session.getExpiry())
-                    .set(MAXINACTIVE, session.getMaxInactiveInterval())
-                    .set(ATTRIBUTES, Blob.copyFrom(baos.toByteArray())).build();
-                     
-            return entity;
-        }
-        
-        public Session sessionFromEntity (Entity entity) throws Exception
-        {
-            if (entity == null)
-                return null;
-
-            final AtomicReference<Session> reference = new AtomicReference<Session>();
-            final AtomicReference<Exception> exception = new AtomicReference<Exception>();
-            Runnable load = new Runnable()
-            {
-                public void run ()
-                {
-                    try
-                    {
-                        //turn an entity into a Session
-                        String clusterId = entity.getString(CLUSTERID);
-                        String contextPath = entity.getString(CONTEXTPATH);
-                        String vhost = entity.getString(VHOST);
-                        long accessed = entity.getLong(ACCESSED);
-                        long lastAccessed = entity.getLong(LASTACCESSED);
-                        long createTime = entity.getLong(CREATETIME);
-                        long cookieSetTime = entity.getLong(COOKIESETTIME);
-                        String lastNode = entity.getString(LASTNODE);
-                        long expiry = entity.getLong(EXPIRY);
-                        long maxInactive = entity.getLong(MAXINACTIVE);
-                        Blob blob = (Blob) entity.getBlob(ATTRIBUTES);
-
-                        Session session = new Session (clusterId, createTime, accessed, maxInactive);
-                        session.setLastNode(lastNode);
-                        session.setContextPath(contextPath);
-                        session.setVHost(vhost);
-                        session.setCookieSetTime(cookieSetTime);
-                        session.setLastAccessedTime(lastAccessed);
-                        session.setLastNode(lastNode);
-                        session.setExpiry(expiry);
-                        try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
-                        {
-                            Object o = ois.readObject();
-                            session.addAttributes((Map<String,Object>)o);
-                        }
-                        reference.set(session);
-                    }
-                    catch (Exception e)
-                    {
-                        exception.set(e);
-                    }
-                }
-            };
-            
-            if (_context==null)
-                load.run();
-            else
-                _context.getContextHandler().handle(null,load);
-   
-           
-            if (exception.get() != null)
-            {
-                exception.get().printStackTrace();
-                throw exception.get();
-            }
-            
-            return reference.get();
-        }
-    }
-    
-    /*
-     * Every time a Session is put into the cache one of these objects
-     * is created to copy the data out of the in-memory session, and 
-     * every time an object is read from the cache one of these objects
-     * a fresh Session object is created based on the data held by this
-     * object.
-     */
-    public class SerializableSessionData implements Serializable
-    {
-        /**
-         * 
-         */
-        private static final long serialVersionUID = -7779120106058533486L;
-        String clusterId;
-        String contextPath;
-        String vhost;
-        long accessed;
-        long lastAccessed;
-        long createTime;
-        long cookieSetTime;
-        String lastNode;
-        long expiry;
-        long maxInactive;
-        Map<String, Object> attributes;
-
-        public SerializableSessionData()
-        {
-
-        }
-
-       
-       public SerializableSessionData(Session s)
-       {
-           clusterId = s.getClusterId();
-           contextPath = s.getContextPath();
-           vhost = s.getVHost();
-           accessed = s.getAccessed();
-           lastAccessed = s.getLastAccessedTime();
-           createTime = s.getCreationTime();
-           cookieSetTime = s.getCookieSetTime();
-           lastNode = s.getLastNode();
-           expiry = s.getExpiry();
-           maxInactive = s.getMaxInactiveInterval();
-           attributes = s.getAttributeMap(); // TODO pointer, not a copy
-       }
-        
-        private void writeObject(java.io.ObjectOutputStream out) throws IOException
-        {  
-            out.writeUTF(clusterId); //session id
-            out.writeUTF(contextPath); //context path
-            out.writeUTF(vhost); //first vhost
-
-            out.writeLong(accessed);//accessTime
-            out.writeLong(lastAccessed); //lastAccessTime
-            out.writeLong(createTime); //time created
-            out.writeLong(cookieSetTime);//time cookie was set
-            out.writeUTF(lastNode); //name of last node managing
-      
-            out.writeLong(expiry); 
-            out.writeLong(maxInactive);
-            out.writeObject(attributes);
-        }
-        
-        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
-        {
-            clusterId = in.readUTF();
-            contextPath = in.readUTF();
-            vhost = in.readUTF();
-            
-            accessed = in.readLong();//accessTime
-            lastAccessed = in.readLong(); //lastAccessTime
-            createTime = in.readLong(); //time created
-            cookieSetTime = in.readLong();//time cookie was set
-            lastNode = in.readUTF(); //last managing node
-            expiry = in.readLong(); 
-            maxInactive = in.readLong();
-            attributes = (HashMap<String,Object>)in.readObject();
-        }
-        
-    }
-    
-
-    
-    /**
+    *//**
      * Session
      *
      * Representation of a session in local memory.
-     */
+     *//*
     public class Session extends MemSession
     {
         
         private ReentrantLock _lock = new ReentrantLock();
         
-        /**
-         * The (canonical) context path for with which this session is associated
-         */
-        private String _contextPath;
-        
-        
-        
-        /**
-         * The time in msec since the epoch at which this session should expire
-         */
-        private long _expiryTime; 
-        
-        
-        /**
-         * Time in msec since the epoch at which this session was last read from cluster
-         */
-        private long _lastSyncTime;
-        
-        
-        /**
-         * The workername of last node known to be managing the session
-         */
-        private String _lastNode;
-        
-        
-        /**
-         * If dirty, session needs to be (re)sent to cluster
-         */
-        protected boolean _dirty=false;
-        
-        
      
+        private long _lastSyncTime;
 
-        /**
-         * Any virtual hosts for the context with which this session is associated
-         */
-        private String _vhost;
-
-        
-        /**
-         * Count of how many threads are active in this session
-         */
         private AtomicInteger _activeThreads = new AtomicInteger(0);
         
         
-        
-        
-        /**
-         * A new session.
-         * 
-         * @param request
-         */
+       
         protected Session (HttpServletRequest request)
         {
-            super(GCloudSessionManager.this,request);
-            long maxInterval = getMaxInactiveInterval();
-            _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-            _lastNode = getSessionIdManager().getWorkerName();
-           setVHost(GCloudSessionManager.getVirtualHost(_context));
-           setContextPath(GCloudSessionManager.getContextPath(_context));
            _activeThreads.incrementAndGet(); //access will not be called on a freshly created session so increment here
         }
         
         
     
-        
-        /**
-         * A restored session.
-         * 
-         * @param sessionId
-         * @param created
-         * @param accessed
-         * @param maxInterval
-         */
-        protected Session (String sessionId, long created, long accessed, long maxInterval)
-        {
-            super(GCloudSessionManager.this, created, accessed, sessionId);
-            _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-        }
-        
-        /** 
+        *//** 
          * Called on entry to the session.
          * 
          * @see org.eclipse.jetty.server.session.AbstractSession#access(long)
-         */
+         *//*
         @Override
         protected boolean access(long time)
         {
@@ -459,10 +122,10 @@
         }
 
 
-        /**
+        *//**
          * Exit from session
          * @see org.eclipse.jetty.server.session.AbstractSession#complete()
-         */
+         *//*
         @Override
         protected void complete()
         {
@@ -511,46 +174,24 @@
             }
         }
         
-        /** Test if the session is stale
+        *//** Test if the session is stale
          * @param atTime
          * @return
-         */
+         *//*
         protected boolean isStale (long atTime)
         {
             return (getStaleIntervalSec() > 0) && (atTime - getLastSyncTime() >= (getStaleIntervalSec()*1000L));
         }
-        
-        
-        /** Test if the session is dirty
-         * @return
-         */
-        protected boolean isDirty ()
-        {
-            return _dirty;
-        }
-
-        /** 
-         * Expire the session.
-         * 
-         * @see org.eclipse.jetty.server.session.AbstractSession#timeout()
-         */
-        @Override
-        protected void timeout()
-        {
-            if (LOG.isDebugEnabled()) LOG.debug("Timing out session {}", getId());
-            super.timeout();
-        }
-        
       
         
-        /**
+        *//**
          * Reload the session from the cluster. If the node that
          * last managed the session from the cluster is ourself,
          * then the session does not need refreshing.
          * NOTE: this method MUST be called with sufficient locks
          * in place to prevent 2 or more concurrent threads from
          * simultaneously updating the session.
-         */
+         *//*
         private void refresh () 
         throws Exception
         {
@@ -612,25 +253,6 @@
         }
 
 
-        public void setExpiry (long expiry)
-        {
-            _expiryTime = expiry;
-        }
-        
-
-        public long getExpiry ()
-        {
-            return _expiryTime;
-        }
-        
-        public boolean isExpiredAt (long time)
-        {
-            if (_expiryTime <= 0)
-                return false; //never expires
-            
-            return  (_expiryTime <= time);
-        }
-        
         public void swapId (String newId, String newNodeId)
         {
             //TODO probably synchronize rather than use the access/complete lock?
@@ -639,69 +261,37 @@
             setNodeId(newNodeId);
             _lock.unlock();
         }
-        
-        @Override
-        public void setAttribute (String name, Object value)
-        {
-            Object old = changeAttribute(name, value);
-            if (value == null && old == null)
-                return; //if same as remove attribute but attribute was already removed, no change
-            
-           _dirty = true;
-        }
-        
-        
-        public String getContextPath()
-        {
-            return _contextPath;
-        }
 
 
-        public void setContextPath(String contextPath)
-        {
-            this._contextPath = contextPath;
-        }
+    }
 
+*/
 
-        public String getVHost()
-        {
-            return _vhost;
-        }
+    
+    /**
+     * 
+     */
+    public GCloudSessionManager()
+    {
+        _sessionDataStore = new GCloudSessionDataStore();
+        _sessionStore = new MemorySessionStore();
+    }
 
+    
+    
 
-        public void setVHost(String vhost)
-        {
-            this._vhost = vhost;
-        }
-        
-        public String getLastNode()
-        {
-            return _lastNode;
-        }
-
-
-        public void setLastNode(String lastNode)
-        {
-            _lastNode = lastNode;
-        }
-
-
-        public long getLastSyncTime()
-        {
-            return _lastSyncTime;
-        }
-
-
-        public void setLastSyncTime(long lastSyncTime)
-        {
-            _lastSyncTime = lastSyncTime;
-        }
-
+    /**
+     * @return
+     */
+    public GCloudSessionDataStore getSessionDataStore()
+    {
+        return _sessionDataStore;
     }
 
 
 
-    
+
+
     /**
      * Start the session manager.
      *
@@ -710,32 +300,7 @@
     @Override
     public void doStart() throws Exception
     {
-        if (_sessionIdManager == null)
-            throw new IllegalStateException("No session id manager defined");
-        
-        GCloudConfiguration config = ((GCloudSessionIdManager)_sessionIdManager).getConfig();
-        if (config == null)
-            throw new IllegalStateException("No gcloud configuration");
-        
-        
-        _datastore = DatastoreFactory.instance().get(config.getDatastoreOptions());
-        _keyFactory = _datastore.newKeyFactory().kind(KIND);
-        _converter = new SessionEntityConverter();       
-        _sessions = new ConcurrentHashMap<String, Session>();
-
-        //try and use a common scheduler, fallback to own
-        _scheduler = getSessionHandler().getServer().getBean(Scheduler.class);
-        if (_scheduler == null)
-        {
-            _scheduler = new ScheduledExecutorScheduler();
-            _ownScheduler = true;
-            _scheduler.start();
-        }
-        else if (!_scheduler.isStarted())
-            throw new IllegalStateException("Shared scheduler not started");
- 
-        setScavengeIntervalSec(getScavengeIntervalSec());
-        
+        ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
         super.doStart();
     }
 
@@ -749,552 +314,16 @@
     public void doStop() throws Exception
     {
         super.doStop();
-
-        if (_task!=null)
-            _task.cancel();
-        _task=null;
-        if (_ownScheduler && _scheduler !=null)
-            _scheduler.stop();
-        _scheduler = null;
-
-        _sessions.clear();
-        _sessions = null;
     }
 
 
 
-    /**
-     * Look for sessions in local memory that have expired.
-     */
-    public void scavenge ()
-    {
-        try
-        {
-            //scavenge in the database every so often
-            scavengeGCloudDataStore();
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Problem scavenging", e);
-        }
-    }
-
  
     
     protected void scavengeGCloudDataStore()
     throws Exception
     {
        
-        //query the datastore for sessions that have expired
-        long now = System.currentTimeMillis();
-        
-        //give a bit of leeway so we don't immediately something that has only just expired a nanosecond ago
-        now = now - (_scavengeIntervalMs/2);
-        
-        if (LOG.isDebugEnabled())
-            LOG.debug("Scavenging for sessions expired before "+now);
-
-
-        GqlQuery.Builder builder = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from "+KIND+" where expiry < @1 limit "+_maxResults);
-        builder.allowLiteral(true);
-        builder.addBinding(now);
-        Query<Entity> query = builder.build();
-        QueryResults<Entity> results = _datastore.run(query);
-        
-        while (results.hasNext())
-        {          
-            Entity sessionEntity = results.next();
-            scavengeSession(sessionEntity);        
-        }
-
+     
     }
-
-    /**
-     * Scavenge a session that has expired
-     * @param e
-     * @throws Exception
-     */
-    protected void scavengeSession (Entity e)
-            throws Exception
-    {
-        long now = System.currentTimeMillis();
-        Session session = _converter.sessionFromEntity(e);
-        if (session == null)
-            return;
-
-        if (LOG.isDebugEnabled())
-            LOG.debug("Scavenging session: {}",session.getId());
-        //if the session isn't in memory already, put it there so we can do a normal timeout call
-         Session memSession =  _sessions.putIfAbsent(session.getId(), session);
-         if (memSession == null)
-         {
-             memSession = session;
-             _sessionsStats.increment();
-         }
-
-        //final check
-        if (memSession.isExpiredAt(now))
-        {
-            if (LOG.isDebugEnabled()) LOG.debug("Session {} is definitely expired", memSession.getId());
-            memSession.timeout();   
-        }
-    }
-
-    public long getScavengeIntervalSec ()
-    {
-        return _scavengeIntervalMs/1000;
-    }
-
-    
-    
-    /**
-     * Set the interval between runs of the scavenger. It should not be run too
-     * often.
-     * 
-     * 
-     * @param sec
-     */
-    public void setScavengeIntervalSec (long sec)
-    {
-
-        long old_period=_scavengeIntervalMs;
-        long period=sec*1000L;
-
-        _scavengeIntervalMs=period;
-
-        if (_scavengeIntervalMs > 0)
-        {
-            //add a bit of variability into the scavenge time so that not all
-            //nodes with the same scavenge time sync up
-            long tenPercent = _scavengeIntervalMs/10;
-            if ((System.currentTimeMillis()%2) == 0)
-                _scavengeIntervalMs += tenPercent;
-            if (LOG.isDebugEnabled())
-                LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
-        }
-        else
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Scavenging disabled"); 
-        }
-
- 
-        
-        synchronized (this)
-        {
-            if (_scheduler != null && (period!=old_period || _task==null))
-            {
-                //clean up any previously scheduled scavenger
-                if (_task!=null)
-                    _task.cancel();
-
-                //start a new one
-                if (_scavengeIntervalMs > 0)
-                {
-                    if (_scavenger == null)
-                        _scavenger = new Scavenger();
-
-                    _task = _scheduler.schedule(_scavenger,_scavengeIntervalMs,TimeUnit.MILLISECONDS);
-                }
-            }
-        }
-    }
-    
-    
-    public long getStaleIntervalSec()
-    {
-        return _staleIntervalSec;
-    }
-
-
-    public void setStaleIntervalSec(long staleIntervalSec)
-    {
-        _staleIntervalSec = staleIntervalSec;
-    }
-    
-    
-    public int getMaxResults()
-    {
-        return _maxResults;
-    }
-
-
-    public void setMaxResults(int maxResults)
-    {
-        if (_maxResults <= 0)
-            _maxResults = DEFAULT_MAX_QUERY_RESULTS;
-        else
-            _maxResults = maxResults;
-    }
-
-
-    /** 
-     * Add a new session for the context related to this session manager
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
-     */
-    @Override
-    protected void addSession(AbstractSession session)
-    {
-        if (session==null)
-            return;
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Adding session({}) to session manager for context {} on worker {}",session.getClusterId(), getContextPath(getContext()),getSessionIdManager().getWorkerName() + " with lastnode="+((Session)session).getLastNode());
-        _sessions.put(session.getClusterId(), (Session)session);
-        
-        try
-        {     
-                session.willPassivate();
-                save(((GCloudSessionManager.Session)session));
-                session.didActivate();
-            
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Unable to store new session id="+session.getId() , e);
-        }
-    }
-
-    /** 
-     * Ask the cluster for the session.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
-     */
-    @Override
-    public AbstractSession getSession(String idInCluster)
-    {
-        Session session = null;
-
-        //try and find the session in this node's memory
-        Session memSession = (Session)_sessions.get(idInCluster);
-
-        if (LOG.isDebugEnabled())
-            LOG.debug("getSession({}) {} in session map",idInCluster,(memSession==null?"not":""));
-
-        long now = System.currentTimeMillis();
-        try
-        {
-            //if the session is not in this node's memory, then load it from the datastore
-            if (memSession == null)
-            {
-                if (LOG.isDebugEnabled())
-                    LOG.debug("getSession({}): loading session data from cluster", idInCluster);
-
-                session = load(makeKey(idInCluster, _context));
-                if (session != null)
-                {
-                    //Check that it wasn't expired
-                    if (session.getExpiry() > 0 && session.getExpiry() <= now)
-                    {
-                        if (LOG.isDebugEnabled()) LOG.debug("getSession ({}): Session expired", idInCluster);
-                        //ensure that the session id for the expired session is deleted so that a new session with the 
-                        //same id cannot be created (because the idInUse() test would succeed)
-                        ((GCloudSessionIdManager)getSessionIdManager()).removeSession(session);
-                        return null;  
-                    }
-
-                    //Update the last worker node to me
-                    session.setLastNode(getSessionIdManager().getWorkerName());                            
-                    //TODO consider saving session here if lastNode was not this node
-
-                    //Check that another thread hasn't loaded the same session
-                    Session existingSession = _sessions.putIfAbsent(idInCluster, session);
-                    if (existingSession != null)
-                    {
-                        //use the one that the other thread inserted
-                        session = existingSession;
-                        LOG.debug("getSession({}): using session loaded by another request thread ", idInCluster);
-                    }
-                    else
-                    {
-                        //indicate that the session was reinflated
-                        session.didActivate();
-                        _sessionsStats.increment();
-                        LOG.debug("getSession({}): loaded session from cluster", idInCluster);
-                    }
-                    return session;
-                }
-                else
-                {
-                    //The requested session does not exist anywhere in the cluster
-                    LOG.debug("getSession({}): No session in cluster matching",idInCluster);
-                    return null;
-                }
-            }
-            else
-            {
-               //The session exists in this node's memory
-               LOG.debug("getSession({}): returning session from local memory ", memSession.getClusterId());
-                return memSession;
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Unable to load session="+idInCluster, e);
-            return null;
-        }
-    }
-    
-    
-
-    /** 
-     * The session manager is stopping.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#shutdownSessions()
-     */
-    @Override
-    protected void shutdownSessions() throws Exception
-    {
-        Set<String> keys = new HashSet<String>(_sessions.keySet());
-        for (String key:keys)
-        {
-            Session session = _sessions.remove(key); //take the session out of the session list
-            //If the session is dirty, then write it to the cluster.
-            //If the session is simply stale do NOT write it to the cluster, as some other node
-            //may have started managing that session - this means that the last accessed/expiry time
-            //will not be updated, meaning it may look like it can expire sooner than it should.
-            try
-            {
-                if (session.isDirty())
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("Saving dirty session {} before exiting ", session.getId());
-                    save(session);
-                }
-            }
-            catch (Exception e)
-            {
-                LOG.warn(e);
-            }
-        }
-    }
-
-
-    @Override
-    protected AbstractSession newSession(HttpServletRequest request)
-    {
-        return new Session(request);
-    }
-
-    /** 
-     * Remove a session from local memory, and delete it from
-     * the cluster cache.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
-     */
-    @Override
-    protected boolean removeSession(String idInCluster)
-    {
-        Session session = (Session)_sessions.remove(idInCluster);
-        try
-        {
-            if (session != null)
-            {
-                delete(session);
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Problem deleting session id="+idInCluster, e);
-        }
-        return session!=null;
-    }
-    
-    
-    
-    
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
-    {
-        Session session = null;
-        try
-        {
-            //take the session with that id out of our managed list
-            session = (Session)_sessions.remove(oldClusterId);
-            if (session != null)
-            {
-                //TODO consider transactionality and ramifications if the session is live on another node
-                delete(session); //delete the old session from the cluster  
-                session.swapId(newClusterId, newNodeId); //update the session
-                _sessions.put(newClusterId, session); //put it into managed list under new key
-                save(session); //put the session under the new id into the cluster
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-
-        super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
-    }
-
-
-    /**
-     * Load a session from the clustered cache.
-     * 
-     * @param key
-     * @return
-     */
-    protected Session load (Key key)
-    throws Exception
-    {
-        if (_datastore == null)
-            throw new IllegalStateException("No DataStore");
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from DataStore", key);
-
-        Entity entity = _datastore.get(key);
-        if (entity == null)
-        {
-            if (LOG.isDebugEnabled()) LOG.debug("No session {} in DataStore ",key);
-            return null;
-        }
-        else
-        {
-            Session session = _converter.sessionFromEntity(entity);
-            session.setLastSyncTime(System.currentTimeMillis());
-            return session;
-        }
-    }
-    
-    
-    
-    /**
-     * Save or update the session to the cluster cache
-     * 
-     * @param session
-     * @throws Exception
-     */
-    protected void save (GCloudSessionManager.Session session)
-    throws Exception
-    {
-        if (_datastore == null)
-            throw new IllegalStateException("No DataStore");
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Writing session {} to DataStore", session.getId());
-    
-        Entity entity = _converter.entityFromSession(session, makeKey(session, _context));
-        _datastore.put(entity);
-        session.setLastSyncTime(System.currentTimeMillis());
-    }
-    
-    
-    
-    /**
-     * Remove the session from the cluster cache.
-     * 
-     * @param session
-     */
-    protected void delete (GCloudSessionManager.Session session)
-    {  
-        if (_datastore == null)
-            throw new IllegalStateException("No DataStore");
-        if (LOG.isDebugEnabled()) LOG.debug("Removing session {} from DataStore", session.getId());
-        _datastore.delete(makeKey(session, _context));
-    }
-
-    
-    /**
-     * Invalidate a session for this context with the given id
-     * 
-     * @param idInCluster
-     */
-    public void invalidateSession (String idInCluster)
-    {
-        Session session = (Session)_sessions.get(idInCluster);
-
-        if (session != null)
-        {
-            session.invalidate();
-        }
-    }
-
-    
-    /**
-     * Make a unique key for this session.
-     * As the same session id can be used across multiple contexts, to
-     * make it unique, the key must be composed of:
-     * <ol>
-     * <li>the id</li>
-     * <li>the context path</li>
-     * <li>the virtual hosts</li>
-     * </ol>
-     * 
-     *TODO consider the difference between getClusterId and getId
-     * @param session
-     * @return
-     */
-    private Key makeKey (Session session, Context context)
-    {
-       return makeKey(session.getId(), context);
-    }
-    
-    /**
-     * Make a unique key for this session.
-     * As the same session id can be used across multiple contexts, to
-     * make it unique, the key must be composed of:
-     * <ol>
-     * <li>the id</li>
-     * <li>the context path</li>
-     * <li>the virtual hosts</li>
-     * </ol>
-     * 
-     *TODO consider the difference between getClusterId and getId
-     * @param session
-     * @return
-     */
-    private Key makeKey (String id, Context context)
-    {
-        String key = getContextPath(context);
-        key = key + "_" + getVirtualHost(context);
-        key = key+"_"+id;
-        return _keyFactory.newKey(key);
-    }
-    
-    /**
-     * Turn the context path into an acceptable string
-     * 
-     * @param context
-     * @return
-     */
-    private static String getContextPath (ContextHandler.Context context)
-    {
-        return canonicalize (context.getContextPath());
-    }
-
-    /**
-     * Get the first virtual host for the context.
-     *
-     * Used to help identify the exact session/contextPath.
-     *
-     * @return 0.0.0.0 if no virtual host is defined
-     */
-    private static String getVirtualHost (ContextHandler.Context context)
-    {
-        String vhost = "0.0.0.0";
-
-        if (context==null)
-            return vhost;
-
-        String [] vhosts = context.getContextHandler().getVirtualHosts();
-        if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
-            return vhost;
-
-        return vhosts[0];
-    }
-
-    /**
-     * Make an acceptable name from a context path.
-     *
-     * @param path
-     * @return
-     */
-    private static String canonicalize (String path)
-    {
-        if (path==null)
-            return "";
-
-        return path.replace('/', '_').replace('.','_').replace('\\','_');
-    }
-
 }
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
new file mode 100644
index 0000000..61e8279
--- /dev/null
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java
@@ -0,0 +1,201 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.session.infinispan;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.server.SessionIdManager;
+import org.eclipse.jetty.server.session.AbstractSessionDataStore;
+import org.eclipse.jetty.server.session.SessionContext;
+import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.infinispan.commons.api.BasicCache;
+
+/**
+ * InfinispanSessionDataStore
+ *
+ *
+ */
+public class InfinispanSessionDataStore extends AbstractSessionDataStore
+{
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+
+    public static final int DEFAULT_IDLE_EXPIRY_MULTIPLE = 2;
+
+
+    /**
+     * Clustered cache of sessions
+     */
+    private BasicCache<String, Object> _cache;
+
+    private SessionIdManager _idMgr = null;
+    
+    
+    private int _idleExpiryMultiple = DEFAULT_IDLE_EXPIRY_MULTIPLE;
+    
+
+    /**
+     * Get the clustered cache instance.
+     * 
+     * @return
+     */
+    public BasicCache<String, Object> getCache() 
+    {
+        return _cache;
+    }
+
+    
+    
+    /**
+     * Set the clustered cache instance.
+     * 
+     * @param cache
+     */
+    public void setCache (BasicCache<String, Object> cache) 
+    {
+        this._cache = cache;
+    }
+
+    public void setSessionIdManager (SessionIdManager idMgr)
+    {
+        _idMgr = idMgr;
+    }
+    
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {  
+        final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        
+        Runnable load = new Runnable()
+        {
+            public void run ()
+            {
+                try
+                {
+
+                    SessionData sd = (SessionData)_cache.get(getCacheKey(id, _context));
+                    reference.set(sd);
+                }
+                catch (Exception e)
+                {
+                    exception.set(e);
+                }
+            }
+        };
+        
+        //ensure the load runs in the context classloader scope
+        _context.run(load);
+        
+        if (exception.get() != null)
+            throw exception.get();
+        
+        return reference.get();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {
+        return (_cache.remove(getCacheKey(id, _context)) != null);
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+       if (candidates == null  || candidates.isEmpty())
+           return candidates;
+       
+       long now = System.currentTimeMillis();
+       
+       Set<String> expired = new HashSet<String>();
+       if (LOG.isDebugEnabled())
+           LOG.debug("Getting expired sessions " + now);
+       
+       for (String candidate:candidates)
+       {
+           try
+           {
+               SessionData sd = load(candidate);
+               if (sd == null || sd.isExpiredAt(now))
+                   expired.add(candidate);
+                   
+           }
+           catch (Exception e)
+           {
+               LOG.warn("Error checking if session {} is expired", candidate, e);
+           }
+       }
+       
+       return expired;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData, boolean)
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        //Put an idle timeout on the cache entry if the session is not immortal - 
+        //if no requests arrive at any node before this timeout occurs, or no node 
+        //scavenges the session before this timeout occurs, the session will be removed.
+        //NOTE: that no session listeners can be called for this.
+        if (data.getMaxInactiveMs() > 0)
+            _cache.put(getCacheKey(id, _context), data, -1, TimeUnit.MILLISECONDS, (data.getMaxInactiveMs() * _idleExpiryMultiple), TimeUnit.MILLISECONDS);
+        else
+            _cache.put(getCacheKey(id, _context), data);
+        
+        //tickle the session id manager to keep the sessionid entry for this session up-to-date
+        if (_idMgr != null && _idMgr instanceof InfinispanSessionIdManager)
+        {
+            ((InfinispanSessionIdManager)_idMgr).touch(id);
+        }
+    }
+    
+    
+    public static String getCacheKey (String id, SessionContext context)
+    {
+        return context.getCanonicalContextPath()+"_"+context.getVhost()+"_"+id;
+    }
+
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+     */
+    @Override
+    public boolean isPassivating()
+    {
+        return true;
+    }
+}
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java
index d7da914..365a592 100644
--- a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java
@@ -28,8 +28,8 @@
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.SessionManager;
 import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.session.AbstractSession;
 import org.eclipse.jetty.server.session.AbstractSessionIdManager;
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.server.session.SessionHandler;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
@@ -70,7 +70,6 @@
     public final static String ID_KEY = "__o.e.j.s.infinispanIdMgr__";
     public static final int DEFAULT_IDLE_EXPIRY_MULTIPLE = 2;
     protected BasicCache<String,Object> _cache;
-    private Server _server;
     private int _idleExpiryMultiple = DEFAULT_IDLE_EXPIRY_MULTIPLE;
 
     
@@ -79,14 +78,12 @@
     
     public InfinispanSessionIdManager(Server server)
     {
-        super();
-        _server = server;
+        super(server);
     }
 
     public InfinispanSessionIdManager(Server server, Random random)
     {
-       super(random);
-       _server = server;
+       super(server, random);
     }
 
     
@@ -123,15 +120,15 @@
      * 
      * This method will consult the cluster.
      * 
-     * @see org.eclipse.jetty.server.SessionIdManager#idInUse(java.lang.String)
+     * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
      */
     @Override
-    public boolean idInUse(String id)
+    public boolean isIdInUse(String id)
     {
         if (id == null)
             return false;
         
-        String clusterId = getClusterId(id);
+        String clusterId = getId(id);
         
         //ask the cluster - this should also tickle the idle expiration timer on the sessionid entry
         //keeping it valid
@@ -147,29 +144,6 @@
         
     }
 
-    /** 
-     * Remember a new in-use session id.
-     * 
-     * This will save the in-use session id to the cluster.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
-     */
-    @Override
-    public void addSession(HttpSession session)
-    {
-        if (session == null)
-            return;
-
-        //insert into the cache and set an idle expiry on the entry that
-        //is based off the max idle time configured for the session. If the
-        //session is immortal, then there is no idle expiry on the corresponding
-        //session id
-        if (session.getMaxInactiveInterval() == 0)
-            insert (((AbstractSession)session).getClusterId());
-        else
-            insert (((AbstractSession)session).getClusterId(), session.getMaxInactiveInterval() * getIdleExpiryMultiple());
-    }
-    
     
     public void setIdleExpiryMultiple (int multiplier)
     {
@@ -185,90 +159,8 @@
         return _idleExpiryMultiple;
     }
     
-    
-    /** 
-     * Remove a session id from the list of in-use ids.
-     * 
-     * This will remvove the corresponding session id from the cluster.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
-     */
-    @Override
-    public void removeSession(HttpSession session)
-    {
-        if (session == null)
-            return;
+   
 
-        //delete from the cache
-        delete (((AbstractSession)session).getClusterId());
-    }
-
-    /** 
-     * Remove a session id. This compels all other contexts who have a session
-     * with the same id to also remove it.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
-     */
-    @Override
-    public void invalidateAll(String id)
-    {
-        //delete the session id from list of in-use sessions
-        delete (id);
-
-
-        //tell all contexts that may have a session object with this id to
-        //get rid of them
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null)
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof InfinispanSessionManager)
-                {
-                    ((InfinispanSessionManager)manager).invalidateSession(id);
-                }
-            }
-        }
-
-    }
-
-    /** 
-     * Change a session id. 
-     * 
-     * Typically this occurs when a previously existing session has passed through authentication.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
-     */
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
-    {
-        //generate a new id
-        String newClusterId = newSessionId(request.hashCode());
-
-        delete(oldClusterId);
-        insert(newClusterId);
-
-
-        //tell all contexts to update the id 
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null) 
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof InfinispanSessionManager)
-                {
-                    ((InfinispanSessionManager)manager).renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
-                }
-            }
-        }
-
-    }
 
     /**
      * Get the cache.
@@ -351,12 +243,12 @@
      * 
      * @param id the session id
      */
-    protected void delete (String id)
+    protected boolean delete (String id)
     {
         if (_cache == null)
             throw new IllegalStateException ("No cache");
         
-        _cache.remove(makeKey(id));
+        return _cache.remove(makeKey(id)) != null;
     }
     
     
@@ -371,4 +263,28 @@
     {
         return ID_KEY+id;
     }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
+     */
+    @Override
+    public void useId(Session session)
+    {
+        if (session == null)
+            return;
+        
+      if (session.getMaxInactiveInterval() == 0)
+            insert (session.getId());
+        else
+            insert (session.getId(), session.getMaxInactiveInterval() * getIdleExpiryMultiple());
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
+     */
+    @Override
+    public boolean removeId(String id)
+    {
+       return delete (id);        
+    }
 }
diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionManager.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionManager.java
index 072d0f1..f5a7b4d 100644
--- a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionManager.java
+++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionManager.java
@@ -18,573 +18,35 @@
 
 package org.eclipse.jetty.session.infinispan;
 
-import java.io.IOException;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.handler.ContextHandler.Context;
-import org.eclipse.jetty.server.session.AbstractSession;
-import org.eclipse.jetty.server.session.AbstractSessionManager;
-import org.eclipse.jetty.server.session.MemSession;
+import org.eclipse.jetty.server.session.AbstractSessionStore;
+import org.eclipse.jetty.server.session.MemorySessionStore;
+import org.eclipse.jetty.server.session.SessionManager;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
-import org.infinispan.Cache;
-import org.infinispan.commons.api.BasicCache;
-import org.omg.CORBA._IDLTypeStub;
+
+
 
 /**
  * InfinispanSessionManager
  * 
- * The data for a session relevant to a particular context is stored in an Infinispan (clustered) cache:
- * <pre>
- * Key:   is the id of the session + the context path + the vhost for the context 
- * Value: is the data of the session
- * </pre>
- * 
- * The key is necessarily complex because the same session id can be in-use by more than one
- * context. In this case, the contents of the session will strictly be different for each
- * context, although the id will be the same.
- * 
- * Sessions are also kept in local memory when they are used by this session manager. This allows
- * multiple different request threads in the same context to call Request.getSession() and
- * obtain the same object.
- * 
- * This session manager support scavenging, which is only done over the set of sessions in its
- * local memory. This can result in some sessions being "stranded" in the cluster cache if no
- * session manager is currently managing it (eg the node managing the session crashed and it
- * was never requested on another node).
+ * Convenience class to create a MemorySessionStore and an InfinispanSessionDataStore.
  * 
  */
-public class InfinispanSessionManager extends AbstractSessionManager
+public class InfinispanSessionManager extends SessionManager
 {
     private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
     
-    /**
-     * Clustered cache of sessions
-     */
-    private BasicCache<String, Object> _cache;
-    
-    
-    /**
-     * Sessions known to this node held in memory
-     */
-    private ConcurrentHashMap<String, InfinispanSessionManager.Session> _sessions;
 
-    
-    /**
-     * The length of time a session can be in memory without being checked against
-     * the cluster. A value of 0 indicates that the session is never checked against
-     * the cluster - the current node is considered to be the master for the session.
-     *
-     */
-    private long _staleIntervalSec = 0;
-    
-    protected Scheduler.Task _task; //scavenge task
-    protected Scheduler _scheduler;
-    protected Scavenger _scavenger;
-    protected long _scavengeIntervalMs = 1000L * 60 * 10; //10mins
-    protected boolean _ownScheduler;
-    
-    
+    protected InfinispanSessionDataStore _sessionDataStore;
 
-    /**
-     * Scavenger
-     *
-     */
-    protected class Scavenger implements Runnable
+
+    public InfinispanSessionManager()
     {
-
-        @Override
-        public void run()
-        {
-           try
-           {
-               scavenge();
-           }
-           finally
-           {
-               if (_scheduler != null && _scheduler.isRunning())
-                   _task = _scheduler.schedule(this, _scavengeIntervalMs, TimeUnit.MILLISECONDS);
-           }
-        }
+        _sessionStore = new MemorySessionStore();
+        _sessionDataStore = new InfinispanSessionDataStore();
     }
     
     
-    /*
-     * Every time a Session is put into the cache one of these objects
-     * is created to copy the data out of the in-memory session, and 
-     * every time an object is read from the cache one of these objects
-     * a fresh Session object is created based on the data held by this
-     * object.
-     */
-    public class SerializableSessionData implements Serializable
-    {
-        /**
-         * 
-         */
-        private static final long serialVersionUID = -7779120106058533486L;
-        String clusterId;
-        String contextPath;
-        String vhost;
-        long accessed;
-        long lastAccessed;
-        long createTime;
-        long cookieSetTime;
-        String lastNode;
-        long expiry;
-        long maxInactive;
-        Map<String, Object> attributes;
-
-        public SerializableSessionData()
-        {
-
-        }
-
-       
-       public SerializableSessionData(Session s)
-       {
-           clusterId = s.getClusterId();
-           contextPath = s.getContextPath();
-           vhost = s.getVHost();
-           accessed = s.getAccessed();
-           lastAccessed = s.getLastAccessedTime();
-           createTime = s.getCreationTime();
-           cookieSetTime = s.getCookieSetTime();
-           lastNode = s.getLastNode();
-           expiry = s.getExpiry();
-           maxInactive = s.getMaxInactiveInterval();
-           attributes = s.getAttributeMap(); // TODO pointer, not a copy
-       }
-        
-        private void writeObject(java.io.ObjectOutputStream out) throws IOException
-        {  
-            out.writeUTF(clusterId); //session id
-            out.writeUTF(contextPath); //context path
-            out.writeUTF(vhost); //first vhost
-
-            out.writeLong(accessed);//accessTime
-            out.writeLong(lastAccessed); //lastAccessTime
-            out.writeLong(createTime); //time created
-            out.writeLong(cookieSetTime);//time cookie was set
-            out.writeUTF(lastNode); //name of last node managing
-      
-            out.writeLong(expiry); 
-            out.writeLong(maxInactive);
-            out.writeObject(attributes);
-        }
-        
-        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
-        {
-            clusterId = in.readUTF();
-            contextPath = in.readUTF();
-            vhost = in.readUTF();
-            
-            accessed = in.readLong();//accessTime
-            lastAccessed = in.readLong(); //lastAccessTime
-            createTime = in.readLong(); //time created
-            cookieSetTime = in.readLong();//time cookie was set
-            lastNode = in.readUTF(); //last managing node
-            expiry = in.readLong(); 
-            maxInactive = in.readLong();
-            attributes = (HashMap<String,Object>)in.readObject();
-        }
-        
-    }
-    
- 
-    
-    
-    /**
-     * Session
-     *
-     * Representation of a session in local memory.
-     */
-    public class Session extends MemSession
-    {
-        
-        private ReentrantLock _lock = new ReentrantLock();
-        
-        /**
-         * The (canonical) context path for with which this session is associated
-         */
-        private String _contextPath;
-        
-        
-        
-        /**
-         * The time in msec since the epoch at which this session should expire
-         */
-        private long _expiryTime; 
-        
-        
-        /**
-         * Time in msec since the epoch at which this session was last read from cluster
-         */
-        private long _lastSyncTime;
-        
-        
-        /**
-         * The workername of last node known to be managing the session
-         */
-        private String _lastNode;
-        
-        
-        /**
-         * If dirty, session needs to be (re)sent to cluster
-         */
-        protected boolean _dirty=false;
-        
-        
-     
-
-        /**
-         * Any virtual hosts for the context with which this session is associated
-         */
-        private String _vhost;
-
-        
-        /**
-         * Count of how many threads are active in this session
-         */
-        private AtomicInteger _activeThreads = new AtomicInteger(0);
-        
-        
-        
-        
-        /**
-         * A new session.
-         * 
-         * @param request the request
-         */
-        protected Session (HttpServletRequest request)
-        {
-            super(InfinispanSessionManager.this,request);
-            long maxInterval = getMaxInactiveInterval();
-            _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-            _lastNode = getSessionIdManager().getWorkerName();
-           setVHost(InfinispanSessionManager.getVirtualHost(_context));
-           setContextPath(InfinispanSessionManager.getContextPath(_context));
-           _activeThreads.incrementAndGet(); //access will not be called on a freshly created session so increment here
-        }
-        
-        
-        protected Session (SerializableSessionData sd)
-        {
-            super(InfinispanSessionManager.this, sd.createTime, sd.accessed, sd.clusterId);
-            _expiryTime = (sd.maxInactive <= 0 ? 0 : (System.currentTimeMillis() + sd.maxInactive*1000L));
-            setLastNode(sd.lastNode);
-            setContextPath(sd.contextPath);
-            setVHost(sd.vhost);
-            addAttributes(sd.attributes);
-        }
-        
-        
-        /**
-         * A restored session.
-         * 
-         * @param sessionId the session id
-         * @param created time created
-         * @param accessed time last accessed
-         * @param maxInterval max expiry interval
-         */
-        protected Session (String sessionId, long created, long accessed, long maxInterval)
-        {
-            super(InfinispanSessionManager.this, created, accessed, sessionId);
-            _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-        }
-        
-        /** 
-         * Called on entry to the session.
-         * 
-         * @see org.eclipse.jetty.server.session.AbstractSession#access(long)
-         */
-        @Override
-        protected boolean access(long time)
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Access session({}) for context {} on worker {}", getId(), getContextPath(), getSessionIdManager().getWorkerName());
-            try
-            {
-
-                long now = System.currentTimeMillis();
-                //lock so that no other thread can call access or complete until the first one has refreshed the session object if necessary
-                _lock.lock();
-                //a request thread is entering
-                if (_activeThreads.incrementAndGet() == 1)
-                {
-                    //if the first thread, check that the session in memory is not stale, if we're checking for stale sessions
-                    if (getStaleIntervalSec() > 0  && (now - getLastSyncTime()) >= (getStaleIntervalSec() * 1000L))
-                    {
-                        if (LOG.isDebugEnabled())
-                            LOG.debug("Acess session({}) for context {} on worker {} stale session. Reloading.", getId(), getContextPath(), getSessionIdManager().getWorkerName());
-                        refresh();
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                LOG.warn(e);
-            }
-            finally
-            {            
-                _lock.unlock();
-            }
-
-            if (super.access(time))
-            {
-                int maxInterval=getMaxInactiveInterval();
-                _expiryTime = (maxInterval <= 0 ? 0 : (time + maxInterval*1000L));
-                return true;
-            }
-            return false;
-        }
-
-
-        /**
-         * Exit from session
-         * @see org.eclipse.jetty.server.session.AbstractSession#complete()
-         */
-        @Override
-        protected void complete()
-        {
-            super.complete();
-
-            //lock so that no other thread that might be calling access can proceed until this complete is done
-            _lock.lock();
-
-            try
-            {
-                //if this is the last request thread to be in the session
-                if (_activeThreads.decrementAndGet() == 0)
-                {
-                    try
-                    {
-                        //an invalid session will already have been removed from the
-                        //local session map and deleted from the cluster. If its valid save
-                        //it to the cluster.
-                        //TODO consider doing only periodic saves if only the last access
-                        //time to the session changes
-                        if (isValid())
-                        {
-                            //if session still valid && its dirty or stale or never been synced, write it to the cluster
-                            //otherwise, we just keep the updated last access time in memory
-                            if (_dirty || getLastSyncTime() == 0 || isStale(System.currentTimeMillis()))
-                            {
-                                willPassivate();
-                                save(this);
-                                didActivate();
-                            }
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        LOG.warn("Problem saving session({})",getId(), e);
-                    } 
-                    finally
-                    {
-                        _dirty = false;
-                    }
-                }
-            }
-            finally
-            {
-                _lock.unlock();
-            }
-        }
-        
-        /** Test if the session is stale
-         * @param atTime time when stale
-         * @return true if stale
-         */
-        protected boolean isStale (long atTime)
-        {
-            return (getStaleIntervalSec() > 0) && (atTime - getLastSyncTime() >= (getStaleIntervalSec()*1000L));
-        }
-        
-        
-        /** Test if the session is dirty
-         * @return true if dirty
-         */
-        protected boolean isDirty ()
-        {
-            return _dirty;
-        }
-
-        /** 
-         * Expire the session.
-         * 
-         * @see org.eclipse.jetty.server.session.AbstractSession#timeout()
-         */
-        @Override
-        protected void timeout()
-        {
-            super.timeout();
-        }
-        
-      
-        
-        /**
-         * Reload the session from the cluster. If the node that
-         * last managed the session from the cluster is ourself,
-         * then the session does not need refreshing.
-         * NOTE: this method MUST be called with sufficient locks
-         * in place to prevent 2 or more concurrent threads from
-         * simultaneously updating the session.
-         */
-        private void refresh ()
-        {
-            //get fresh copy from the cluster
-            Session fresh = load(makeKey(getClusterId(), _context));
-
-            //if the session no longer exists, invalidate
-            if (fresh == null)
-            {
-                invalidate();
-                return;
-            }
-
-            //cluster copy assumed to be the same as we were the last
-            //node to manage it
-            if (fresh.getLastNode().equals(getLastNode()))
-                return;
-
-            setLastNode(getSessionIdManager().getWorkerName());
-            
-            //prepare for refresh
-            willPassivate();
-
-            //if fresh has no attributes, remove them
-            if (fresh.getAttributes() == 0)
-                this.clearAttributes();
-            else
-            {
-                //reconcile attributes
-                for (String key:fresh.getAttributeMap().keySet())
-                {
-                    Object freshvalue = fresh.getAttribute(key);
-
-                    //session does not already contain this attribute, so bind it
-                    if (getAttribute(key) == null)
-                    { 
-                        doPutOrRemove(key,freshvalue);
-                        bindValue(key,freshvalue);
-                    }
-                    else //session already contains this attribute, update its value
-                    {
-                        doPutOrRemove(key,freshvalue);
-                    }
-
-                }
-                // cleanup, remove values from session, that don't exist in data anymore:
-                for (String key : getNames())
-                {
-                    if (fresh.getAttribute(key) == null)
-                    {
-                        Object oldvalue = getAttribute(key);
-                        doPutOrRemove(key,null);
-                        unbindValue(key,oldvalue);
-                    }
-                }
-            }
-            //finish refresh
-            didActivate();
-        }
-
-
-        public void setExpiry (long expiry)
-        {
-            _expiryTime = expiry;
-        }
-        
-
-        public long getExpiry ()
-        {
-            return _expiryTime;
-        }
-        
-        public void swapId (String newId, String newNodeId)
-        {
-            //TODO probably synchronize rather than use the access/complete lock?
-            _lock.lock();
-            setClusterId(newId);
-            setNodeId(newNodeId);
-            _lock.unlock();
-        }
-        
-        @Override
-        public void setAttribute (String name, Object value)
-        {
-            Object old = changeAttribute(name, value);
-            if (value == null && old == null)
-                return; //if same as remove attribute but attribute was already removed, no change
-            
-           _dirty = true;
-        }
-        
-        
-        public String getContextPath()
-        {
-            return _contextPath;
-        }
-
-
-        public void setContextPath(String contextPath)
-        {
-            this._contextPath = contextPath;
-        }
-
-
-        public String getVHost()
-        {
-            return _vhost;
-        }
-
-
-        public void setVHost(String vhost)
-        {
-            this._vhost = vhost;
-        }
-        
-        public String getLastNode()
-        {
-            return _lastNode;
-        }
-
-
-        public void setLastNode(String lastNode)
-        {
-            _lastNode = lastNode;
-        }
-
-
-        public long getLastSyncTime()
-        {
-            return _lastSyncTime;
-        }
-
-
-        public void setLastSyncTime(long lastSyncTime)
-        {
-            _lastSyncTime = lastSyncTime;
-        }
-
-    }
-
-
-
     
     /**
      * Start the session manager.
@@ -597,24 +59,9 @@
         if (_sessionIdManager == null)
             throw new IllegalStateException("No session id manager defined");
         
-        if (_cache == null)
-            throw new IllegalStateException("No session cache defined");
-        
-        _sessions = new ConcurrentHashMap<String, Session>();
-
-        //try and use a common scheduler, fallback to own
-        _scheduler = getSessionHandler().getServer().getBean(Scheduler.class);
-        if (_scheduler == null)
-        {
-            _scheduler = new ScheduledExecutorScheduler();
-            _ownScheduler = true;
-            _scheduler.start();
-        }
-        else if (!_scheduler.isStarted())
-            throw new IllegalStateException("Shared scheduler not started");
- 
-        setScavengeInterval(getScavengeInterval());
-        
+        ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
+        _sessionDataStore.setSessionIdManager(_sessionIdManager);
+       
         super.doStart();
     }
 
@@ -629,544 +76,16 @@
     {
         super.doStop();
 
-        if (_task!=null)
-            _task.cancel();
-        _task=null;
-        if (_ownScheduler && _scheduler !=null)
-            _scheduler.stop();
-        _scheduler = null;
-        
-        _sessions.clear();
-        _sessions = null;
-    }
-    
-    
-    
-    /**
-     * Look for sessions in local memory that have expired.
-     */
-    /**
-     * 
-     */
-    public void scavenge ()
-    {
-        Set<String> candidateIds = new HashSet<String>();
-        long now = System.currentTimeMillis();
-        
-        LOG.info("SessionManager for context {} scavenging at {} ", getContextPath(getContext()), now);
-        for (Map.Entry<String, Session> entry:_sessions.entrySet())
-        {
-            long expiry = entry.getValue().getExpiry();
-            if (expiry > 0 && expiry < now)
-                candidateIds.add(entry.getKey());
-        }
-
-        for (String candidateId:candidateIds)
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Session {} candidate for expiry", candidateId);
-            
-            Session candidateSession = _sessions.get(candidateId);
-            if (candidateSession != null)
-            {
-                //double check the state of the session in the cache, as the
-                //session may have migrated to another node. This leaves a window
-                //where the cached session may have been changed by another node
-                Session cachedSession = load(makeKey(candidateId, _context));
-                if (cachedSession == null)
-                {
-                   if (LOG.isDebugEnabled()) LOG.debug("Locally expired session({}) does not exist in cluster ",candidateId);
-                    //the session no longer exists, do a full invalidation
-                    candidateSession.timeout();
-                }
-                else if (getSessionIdManager().getWorkerName().equals(cachedSession.getLastNode()))
-                {
-                    if (LOG.isDebugEnabled()) LOG.debug("Expiring session({}) local to session manager",candidateId);
-                    //if I am the master of the session then it can be timed out
-                    candidateSession.timeout();
-                }
-                else
-                {
-                    //some other node is the master of the session, simply remove it from my memory
-                    if (LOG.isDebugEnabled()) LOG.debug("Session({}) not local to this session manager, removing from local memory", candidateId);
-                    candidateSession.willPassivate();
-                    _sessions.remove(candidateSession.getClusterId());
-                    _sessionsStats.decrement();
-                }
-
-            }
-        }
-    }
-    
-    
-
-    public long getScavengeInterval ()
-    {
-        return _scavengeIntervalMs/1000;
     }
 
-    
-    
-    /**
-     * Set the interval between runs of the scavenger. It should not be run too
-     * often.
-     * 
-     * 
-     * @param sec scavenge interval in seconds
-     */
-    public void setScavengeInterval (long sec)
-    {
-        if (sec<=0)
-            sec=60;
-
-        long old_period=_scavengeIntervalMs;
-        long period=sec*1000L;
-
-        _scavengeIntervalMs=period;
-
-        //add a bit of variability into the scavenge time so that not all
-        //nodes with the same scavenge time sync up
-        long tenPercent = _scavengeIntervalMs/10;
-        if ((System.currentTimeMillis()%2) == 0)
-            _scavengeIntervalMs += tenPercent;
-
-        if (LOG.isDebugEnabled())
-            LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
-        
-        synchronized (this)
-        {
-            if (_scheduler != null && (period!=old_period || _task==null))
-            {
-                if (_task!=null)
-                    _task.cancel();
-                if (_scavenger == null)
-                    _scavenger = new Scavenger();
-                
-                _task = _scheduler.schedule(_scavenger,_scavengeIntervalMs,TimeUnit.MILLISECONDS);
-            }
-        }
-    }
-    
-    
-    
-
-    /**
-     * Get the clustered cache instance.
-     * 
-     * @return the cache
-     */
-    public BasicCache<String, Object> getCache() 
-    {
-        return _cache;
-    }
-
-    
-    
-    /**
-     * Set the clustered cache instance.
-     * 
-     * @param cache the cache
-     */
-    public void setCache (BasicCache<String, Object> cache) 
-    {
-        this._cache = cache;
-    }
-
-
-    
-    
-    
-    public long getStaleIntervalSec()
-    {
-        return _staleIntervalSec;
-    }
-
-
-    public void setStaleIntervalSec(long staleIntervalSec)
-    {
-        _staleIntervalSec = staleIntervalSec;
-    }
-
-
-    /** 
-     * Add a new session for the context related to this session manager
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
-     */
-    @Override
-    protected void addSession(AbstractSession session)
-    {
-        if (session==null)
-            return;
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Adding session({}) to session manager for context {} on worker {}",session.getClusterId(), getContextPath(getContext()),getSessionIdManager().getWorkerName() + " with lastnode="+((Session)session).getLastNode());
-        _sessions.put(session.getClusterId(), (Session)session);
-        
-        try
-        {     
-                session.willPassivate();
-                save(((InfinispanSessionManager.Session)session));
-                session.didActivate();
-            
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Unable to store new session id="+session.getId() , e);
-        }
-    }
-
-    /** 
-     * Ask the cluster for the session.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
-     */
-    @Override
-    public AbstractSession getSession(String idInCluster)
-    {
-        Session session = null;
-
-        //try and find the session in this node's memory
-        Session memSession = (Session)_sessions.get(idInCluster);
-
-        if (LOG.isDebugEnabled())
-            LOG.debug("getSession({}) {} in session map",idInCluster,(memSession==null?"not":""));
-
-        long now = System.currentTimeMillis();
-        try
-        {
-            //if the session is not in this node's memory, then load it from the cluster cache
-            if (memSession == null)
-            {
-                if (LOG.isDebugEnabled())
-                    LOG.debug("getSession({}): loading session data from cluster", idInCluster);
-
-                session = load(makeKey(idInCluster, _context));
-                if (session != null)
-                {
-                    //We retrieved a session with the same key from the database
-
-                    //Check that it wasn't expired
-                    if (session.getExpiry() > 0 && session.getExpiry() <= now)
-                    {
-                        if (LOG.isDebugEnabled()) LOG.debug("getSession ({}): Session expired", idInCluster);
-                        //ensure that the session id for the expired session is deleted so that a new session with the 
-                        //same id cannot be created (because the idInUse() test would succeed)
-                        ((InfinispanSessionIdManager)getSessionIdManager()).removeSession(session);
-                        return null;  
-                    }
-
-                    //Update the last worker node to me
-                    session.setLastNode(getSessionIdManager().getWorkerName());                            
-                    //TODO consider saving session here if lastNode was not this node
-
-                    //Check that another thread hasn't loaded the same session
-                    Session existingSession = _sessions.putIfAbsent(idInCluster, session);
-                    if (existingSession != null)
-                    {
-                        //use the one that the other thread inserted
-                        session = existingSession;
-                        LOG.debug("getSession({}): using session loaded by another request thread ", idInCluster);
-                    }
-                    else
-                    {
-                        //indicate that the session was reinflated
-                        session.didActivate();
-                        _sessionsStats.increment();
-                        LOG.debug("getSession({}): loaded session from cluster", idInCluster);
-                    }
-                    return session;
-                }
-                else
-                {
-                    //The requested session does not exist anywhere in the cluster
-                    LOG.debug("getSession({}): No session in cluster matching",idInCluster);
-                    return null;
-                }
-            }
-            else
-            {
-               //The session exists in this node's memory
-               LOG.debug("getSession({}): returning session from local memory ", memSession.getClusterId());
-                return memSession;
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Unable to load session="+idInCluster, e);
-            return null;
-        }
-    }
-    
-    
-
-    /** 
-     * The session manager is stopping.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#shutdownSessions()
-     */
-    @Override
-    protected void shutdownSessions() throws Exception
-    {
-        Set<String> keys = new HashSet<String>(_sessions.keySet());
-        for (String key:keys)
-        {
-            Session session = _sessions.remove(key); //take the session out of the session list
-            //If the session is dirty, then write it to the cluster.
-            //If the session is simply stale do NOT write it to the cluster, as some other node
-            //may have started managing that session - this means that the last accessed/expiry time
-            //will not be updated, meaning it may look like it can expire sooner than it should.
-            try
-            {
-                if (session.isDirty())
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("Saving dirty session {} before exiting ", session.getId());
-                    save(session);
-                }
-            }
-            catch (Exception e)
-            {
-                LOG.warn(e);
-            }
-        }
-    }
-
-
-    @Override
-    protected AbstractSession newSession(HttpServletRequest request)
-    {
-        return new Session(request);
-    }
-
-    /** 
-     * Remove a session from local memory, and delete it from
-     * the cluster cache.
-     * 
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
-     */
-    @Override
-    protected boolean removeSession(String idInCluster)
-    {
-        Session session = (Session)_sessions.remove(idInCluster);
-        try
-        {
-            if (session != null)
-                delete(session);
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Problem deleting session id="+idInCluster, e);
-        }
-        return session!=null;
-    }
-    
-    
-    
-    
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
-    {
-        Session session = null;
-        try
-        {
-            //take the session with that id out of our managed list
-            session = (Session)_sessions.remove(oldClusterId);
-            if (session != null)
-            {
-                //TODO consider transactionality and ramifications if the session is live on another node
-                delete(session); //delete the old session from the cluster  
-                session.swapId(newClusterId, newNodeId); //update the session
-                _sessions.put(newClusterId, session); //put it into managed list under new key
-                save(session); //put the session under the new id into the cluster
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-
-        super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
-    }
 
 
     /**
-     * Load a session from the clustered cache.
-     * 
-     * @param key the session key
-     * @return the session
-     */
-    protected Session load (String key)
-    {
-        if (_cache == null)
-            throw new IllegalStateException("No cache");
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from cluster", key);
-
-        SerializableSessionData storableSession = (SerializableSessionData)_cache.get(key);
-        if (storableSession == null)
-        {
-            if (LOG.isDebugEnabled()) LOG.debug("No session {} in cluster ",key);
-            return null;
-        }
-        else
-        {
-            Session session = new Session (storableSession);
-            session.setLastSyncTime(System.currentTimeMillis());
-            return session;
-        }
-    }
-    
-    
-    
-    /**
-     * Save or update the session to the cluster cache
-     * 
-     * @param session the session
-     * @throws Exception if unable to save
-     */
-    protected void save (InfinispanSessionManager.Session session)
-    throws Exception
-    {
-        if (_cache == null)
-            throw new IllegalStateException("No cache");
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Writing session {} to cluster", session.getId());
-    
-        SerializableSessionData storableSession = new SerializableSessionData(session);
-
-        //Put an idle timeout on the cache entry if the session is not immortal - 
-        //if no requests arrive at any node before this timeout occurs, or no node 
-        //scavenges the session before this timeout occurs, the session will be removed.
-        //NOTE: that no session listeners can be called for this.
-        InfinispanSessionIdManager sessionIdManager = (InfinispanSessionIdManager)getSessionIdManager();
-        if (storableSession.maxInactive > 0)
-            _cache.put(makeKey(session, _context), storableSession, -1, TimeUnit.SECONDS, storableSession.maxInactive*sessionIdManager.getIdleExpiryMultiple(), TimeUnit.SECONDS);
-        else
-            _cache.put(makeKey(session, _context), storableSession);
-        
-        //tickle the session id manager to keep the sessionid entry for this session up-to-date
-        sessionIdManager.touch(session.getClusterId());
-        
-        session.setLastSyncTime(System.currentTimeMillis());
-    }
-    
-    
-    
-    /**
-     * Remove the session from the cluster cache.
-     * 
-     * @param session the session
-     */
-    protected void delete (InfinispanSessionManager.Session session)
-    {  
-        if (_cache == null)
-            throw new IllegalStateException("No cache");
-        if (LOG.isDebugEnabled()) LOG.debug("Removing session {} from cluster", session.getId());
-        _cache.remove(makeKey(session, _context));
-    }
-
-    
-    /**
-     * Invalidate a session for this context with the given id
-     * 
-     * @param idInCluster session id in cluster
-     */
-    public void invalidateSession (String idInCluster)
-    {
-        Session session = (Session)_sessions.get(idInCluster);
-
-        if (session != null)
-        {
-            session.invalidate();
-        }
-    }
-
-    
-    /**
-     * Make a unique key for this session.
-     * As the same session id can be used across multiple contexts, to
-     * make it unique, the key must be composed of:
-     * <ol>
-     * <li>the id</li>
-     * <li>the context path</li>
-     * <li>the virtual hosts</li>
-     * </ol>
-     * 
-     *TODO consider the difference between getClusterId and getId
-     * @param session
      * @return
      */
-    private String makeKey (Session session, Context context)
+    public InfinispanSessionDataStore getSessionDataStore()
     {
-       return makeKey(session.getId(), context);
-    }
-    
-    /**
-     * Make a unique key for this session.
-     * As the same session id can be used across multiple contexts, to
-     * make it unique, the key must be composed of:
-     * <ol>
-     * <li>the id</li>
-     * <li>the context path</li>
-     * <li>the virtual hosts</li>
-     * </ol>
-     * 
-     *TODO consider the difference between getClusterId and getId
-     * @param session
-     * @return
-     */
-    private String makeKey (String id, Context context)
-    {
-        String key = getContextPath(context);
-        key = key + "_" + getVirtualHost(context);
-        key = key+"_"+id;
-        return key;
-    }
-    
-    /**
-     * Turn the context path into an acceptable string
-     * 
-     * @param context
-     * @return
-     */
-    private static String getContextPath (ContextHandler.Context context)
-    {
-        return canonicalize (context.getContextPath());
-    }
-
-    /**
-     * Get the first virtual host for the context.
-     *
-     * Used to help identify the exact session/contextPath.
-     *
-     * @return 0.0.0.0 if no virtual host is defined
-     */
-    private static String getVirtualHost (ContextHandler.Context context)
-    {
-        String vhost = "0.0.0.0";
-
-        if (context==null)
-            return vhost;
-
-        String [] vhosts = context.getContextHandler().getVirtualHosts();
-        if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
-            return vhost;
-
-        return vhosts[0];
-    }
-
-    /**
-     * Make an acceptable name from a context path.
-     *
-     * @param path
-     * @return
-     */
-    private static String canonicalize (String path)
-    {
-        if (path==null)
-            return "";
-
-        return path.replace('/', '_').replace('.','_').replace('\\','_');
+        return _sessionDataStore;
     }
 
 }
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java
deleted file mode 100644
index 149caa3..0000000
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSession.java
+++ /dev/null
@@ -1,224 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.nosql;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.server.session.MemSession;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-
-/* ------------------------------------------------------------ */
-public class NoSqlSession extends MemSession
-{
-    private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
-
-    private final NoSqlSessionManager _manager;
-    private Set<String> _dirty;
-    private final AtomicInteger _active = new AtomicInteger();
-    private Object _version;
-    private long _lastSync;
-
-    /* ------------------------------------------------------------ */
-    public NoSqlSession(NoSqlSessionManager manager, HttpServletRequest request)
-    {
-        super(manager, request);
-        _manager=manager;
-        _active.incrementAndGet();
-    }
-    
-    /* ------------------------------------------------------------ */
-    public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId, Object version)
-    {
-        super(manager, created,accessed,clusterId);
-        _manager=manager;
-        _version=version;
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    public Object doPutOrRemove(String name, Object value)
-    {
-        synchronized (this)
-        {
-            Object old = super.doPutOrRemove(name,value);
-            
-            if (_manager.getSavePeriod()==-2)
-            {
-                save(true);
-            }
-            return old;
-        }
-    }
-    
-    
-
-    @Override
-    public void setAttribute(String name, Object value)
-    {
-        Object old = changeAttribute(name,value);
-        if (value == null && old == null)
-            return; //not dirty, no change
-        
-        if (value==null || !value.equals(old))
-        {
-            if (_dirty==null)
-            {
-                _dirty=new HashSet<String>();
-            }
-            
-            _dirty.add(name);
-        }
-    }
-    
-    
-
-    @Override
-    protected void timeout() throws IllegalStateException
-    {
-        super.timeout();
-    }
-
-
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void checkValid() throws IllegalStateException
-    {
-        super.checkValid();
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected boolean access(long time)
-    {
-        __log.debug("NoSqlSession:access:active {} time {}", _active, time);
-        if (_active.incrementAndGet()==1)
-        {
-            long period=_manager.getStalePeriod()*1000L;
-            if (period==0)
-                refresh();
-            else if (period>0)
-            {
-                long stale=time-_lastSync;
-                __log.debug("NoSqlSession:access:stale "+stale);
-                if (stale>period)
-                    refresh();
-            }
-        }
-
-        return super.access(time);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void complete()
-    {
-        super.complete();
-        if(_active.decrementAndGet()==0)
-        {
-            switch(_manager.getSavePeriod())
-            {
-                case 0: 
-                    save(isValid());
-                    break;
-                case 1:
-                    if (isDirty())
-                        save(isValid());
-                    break;
-
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doInvalidate() throws IllegalStateException
-    {
-        super.doInvalidate();
-        //jb why save here? if the session is invalidated it should be removed
-        save(false);
-    }
-    
-    /* ------------------------------------------------------------ */
-    protected void save(boolean activateAfterSave)
-    {
-        synchronized (this)
-        {
-            _version=_manager.save(this,_version,activateAfterSave);
-            _lastSync=getAccessed();
-        }
-    }
-
-
-    /* ------------------------------------------------------------ */
-    protected void refresh()
-    {
-        synchronized (this)
-        {
-            _version=_manager.refresh(this,_version);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    public boolean isDirty()
-    {
-        synchronized (this)
-        {
-            return _dirty!=null && !_dirty.isEmpty();
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    public Set<String> takeDirty()
-    {
-        synchronized (this)
-        {
-            Set<String> dirty=_dirty;
-            if (dirty==null)
-                dirty= new HashSet<String>();
-            else
-                _dirty=null;
-            return dirty;
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    public Object getVersion()
-    {
-        return _version;
-    }
-
-    @Override
-    public void setClusterId(String clusterId)
-    {
-        super.setClusterId(clusterId);
-    }
-
-    @Override
-    public void setNodeId(String nodeId)
-    {
-        super.setNodeId(nodeId);
-    }
-}
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java
new file mode 100644
index 0000000..aa296a7
--- /dev/null
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java
@@ -0,0 +1,98 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.nosql;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jetty.server.session.AbstractSessionDataStore;
+import org.eclipse.jetty.server.session.SessionData;
+
+
+/**
+ * NoSqlSessionDataStore
+ *
+ *
+ */
+public abstract class NoSqlSessionDataStore extends AbstractSessionDataStore
+{
+    
+    public class NoSqlSessionData extends SessionData
+    {
+        private Object _version;
+        private Set<String> _dirtyAttributes = new HashSet<String>();
+        
+
+        /**
+         * @param id
+         * @param cpath
+         * @param vhost
+         * @param created
+         * @param accessed
+         * @param lastAccessed
+         * @param maxInactiveMs
+         */
+        public NoSqlSessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs)
+        {
+            super(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs);
+        }
+        
+        public void setVersion (Object v)
+        {
+            _version = v;
+        }
+        
+        public Object getVersion ()
+        {
+            return _version;
+        }
+
+        @Override
+        public void setDirty(String name)
+        {
+            super.setDirty(name);
+            _dirtyAttributes.add(name);
+        }
+        
+        
+        public Set<String> takeDirtyAttributes()
+        {
+            Set<String> copy = new HashSet<>(_dirtyAttributes);
+            _dirtyAttributes.clear();
+            return copy;
+            
+        }
+        
+        public Set<String> getAllAttributeNames ()
+        {
+            return new HashSet<String>(_attributes.keySet());
+        }
+    }
+
+
+    @Override
+    public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
+    {
+        return new NoSqlSessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
+    }
+    
+    
+
+}
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java
deleted file mode 100644
index 51b8d60..0000000
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionManager.java
+++ /dev/null
@@ -1,435 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.nosql;
-
-import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.session.AbstractSession;
-import org.eclipse.jetty.server.session.AbstractSessionManager;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * NoSqlSessionManager
- *
- * Base class for SessionManager implementations using nosql frameworks
- */
-public abstract class NoSqlSessionManager extends AbstractSessionManager implements SessionManager
-{
-    private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
-
-    protected final ConcurrentMap<String,NoSqlSession> _sessions=new ConcurrentHashMap<String,NoSqlSession>();
-
-    private int _stalePeriod=0;
-    private int _savePeriod=0;
-    private int _idlePeriod=-1;
-    private boolean _invalidateOnStop;
-    private boolean _preserveOnStop = true;
-    private boolean _saveAllAttributes;
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart()
-     */
-    @Override
-    public void doStart() throws Exception
-    {
-        super.doStart();
-       
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void addSession(AbstractSession session)
-    {
-        if (isRunning())
-        {
-            //add into memory
-            _sessions.put(session.getClusterId(),(NoSqlSession)session);
-            //add into db
-            ((NoSqlSession)session).save(true);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public AbstractSession getSession(String idInCluster)
-    {
-        NoSqlSession session = _sessions.get(idInCluster);
-        __log.debug("getSession {} ", session );
-        
-        if (session==null)
-        {
-            //session not in this node's memory, load it
-            session=loadSession(idInCluster);
-            
-            if (session!=null)
-            {
-                //session exists, check another request thread hasn't loaded it too
-                NoSqlSession race=_sessions.putIfAbsent(idInCluster,session);
-                if (race!=null)
-                {
-                    session.willPassivate();
-                    session.clearAttributes();
-                    session=race;
-                }
-                else
-                {
-                    __log.debug("session loaded ", idInCluster);
-                    _sessionsStats.increment();
-                }
-                
-                //check if the session we just loaded has actually expired, maybe while we weren't running
-                if (getMaxInactiveInterval() > 0 && session.getAccessed() > 0 && ((getMaxInactiveInterval()*1000L)+session.getAccessed()) < System.currentTimeMillis())
-                {
-                    __log.debug("session expired ", idInCluster);
-                    expire(idInCluster);
-                    session = null;
-                }
-            }
-            else
-                __log.debug("session does not exist {}", idInCluster);
-        }
-
-        return session;
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void shutdownSessions() throws Exception
-    {
-        //If we are stopping, and we're preserving sessions, then we want to
-        //save all of the sessions (including those that have been added during this method call)
-        //and then just remove them from memory.
-        
-        //If we don't wish to preserve sessions and we're stopping, then we should invalidate
-        //the session (which may remove it).
-        long gracefulStopMs = getContextHandler().getServer().getStopTimeout();
-        long stopTime = 0;
-        if (gracefulStopMs > 0)
-            stopTime = System.nanoTime() + (TimeUnit.NANOSECONDS.convert(gracefulStopMs, TimeUnit.MILLISECONDS));        
-        
-        ArrayList<NoSqlSession> sessions=new ArrayList<NoSqlSession>(_sessions.values());
-
-        // loop while there are sessions, and while there is stop time remaining, or if no stop time, just 1 loop
-        while (sessions.size() > 0 && ((stopTime > 0 && (System.nanoTime() < stopTime)) || (stopTime == 0)))
-        {
-            for (NoSqlSession session : sessions)
-            {
-                if (isPreserveOnStop())
-                {
-                    //we don't want to delete the session, so save the session
-                    //and remove from memory
-                    session.save(false);
-                    _sessions.remove(session.getClusterId());
-                }
-                else
-                {
-                  //invalidate the session so listeners will be called and also removes the session
-                  session.invalidate();
-                }
-            }
-            
-            //check if we should terminate our loop if we're not using the stop timer
-            if (stopTime == 0)
-            {
-                break;
-            }
-            // Get any sessions that were added by other requests during processing and go around the loop again
-            sessions=new ArrayList<NoSqlSession>(_sessions.values());
-        }
-    }
-    
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected AbstractSession newSession(HttpServletRequest request)
-    {
-        return new NoSqlSession(this,request);
-    }
-
-    /* ------------------------------------------------------------ */
-    /** Remove the session from the in-memory list for this context.
-     * Also remove the context sub-document for this session id from the db.
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
-     */
-    @Override
-    protected boolean removeSession(String idInCluster)
-    {
-        NoSqlSession session = _sessions.remove(idInCluster);
-
-        try
-        {
-            if (session != null)
-            {
-                return remove(session);
-            }
-        }
-        catch (Exception e)
-        {
-            __log.warn("Problem deleting session {}", idInCluster,e);
-        }
-
-        return session != null;
-
-    }
-
-    /* ------------------------------------------------------------ */
-    protected void expire( String idInCluster )
-    {
-        //get the session from memory
-        NoSqlSession session = _sessions.get(idInCluster);
-
-        try
-        {
-            if (session == null)
-            {
-                //we need to expire the session with its listeners, so load it
-                session = loadSession(idInCluster);
-            }
-
-            if (session != null)
-                session.timeout();
-        }
-        catch (Exception e)
-        {
-            __log.warn("Problem expiring session {}", idInCluster,e);
-        }
-    }
-
-
-    public void invalidateSession (String idInCluster)
-    {
-        NoSqlSession session = _sessions.get(idInCluster);
-        try
-        {
-            __log.debug("invalidating session {}", idInCluster);
-            if (session != null)
-            {
-                session.invalidate();
-            }
-        }
-        catch (Exception e)
-        {
-            __log.warn("Problem invalidating session {}", idInCluster,e); 
-        }
-    }
-
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * The State Period is the maximum time in seconds that an in memory session is allows to be stale:
-     * <ul>  
-     * <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
-     * <li>If the state period is set to a value &lt; 0, then no staleness check will be made.</li>
-     * <li>If the state period is set to 0, then a staleness check is made whenever the active request count goes from 0 to 1.</li>
-     * </ul>
-     * @return the stalePeriod in seconds
-     */
-    public int getStalePeriod()
-    {
-        return _stalePeriod;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * The State Period is the maximum time in seconds that an in memory session is allows to be stale:
-     * <ul>  
-     * <li>If this period is exceeded, the DB will be checked to see if a more recent version is available.</li>
-     * <li>If the state period is set to a value &lt; 0, then no staleness check will be made.</li>
-     * <li>If the state period is set to 0, then a staleness check is made whenever the active request count goes from 0 to 1.</li>
-     * </ul>
-     * @param stalePeriod the stalePeriod in seconds
-     */
-    public void setStalePeriod(int stalePeriod)
-    {
-        _stalePeriod = stalePeriod;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * The Save Period is the time in seconds between saves of a dirty session to the DB.  
-     * When this period is exceeded, the a dirty session will be written to the DB: <ul>
-     * <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
-     * <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
-     * <li>a save period of 0 means the session is written to the DB whenever the active request count goes from 1 to 0.</li>
-     * <li>a save period of 1 means the session is written to the DB whenever the active request count goes from 1 to 0 and the session is dirty.</li>
-     * <li>a save period of &gt; 1 means the session is written after that period in seconds of being dirty.</li>
-     * </ul>
-     * @return the savePeriod -2,-1,0,1 or the period in seconds &gt;=2 
-     */
-    public int getSavePeriod()
-    {
-        return _savePeriod;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * The Save Period is the time in seconds between saves of a dirty session to the DB.  
-     * When this period is exceeded, the a dirty session will be written to the DB: <ul>
-     * <li>a save period of -2 means the session is written to the DB whenever setAttribute is called.</li>
-     * <li>a save period of -1 means the session is never saved to the DB other than on a shutdown</li>
-     * <li>a save period of 0 means the session is written to the DB whenever the active request count goes from 1 to 0.</li>
-     * <li>a save period of 1 means the session is written to the DB whenever the active request count goes from 1 to 0 and the session is dirty.</li>
-     * <li>a save period of &gt; 1 means the session is written after that period in seconds of being dirty.</li>
-     * </ul>
-     * @param savePeriod the savePeriod -2,-1,0,1 or the period in seconds &gt;=2 
-     */
-    public void setSavePeriod(int savePeriod)
-    {
-        _savePeriod = savePeriod;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * The Idle Period is the time in seconds before an in memory session is passivated.
-     * When this period is exceeded, the session will be passivated and removed from memory.  If the session was dirty, it will be written to the DB.
-     * If the idle period is set to a value &lt; 0, then the session is never idled.
-     * If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
-     * @return the idlePeriod
-     */
-    public int getIdlePeriod()
-    {
-        return _idlePeriod;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * The Idle Period is the time in seconds before an in memory session is passivated.
-     * When this period is exceeded, the session will be passivated and removed from memory.  If the session was dirty, it will be written to the DB.
-     * If the idle period is set to a value &lt; 0, then the session is never idled.
-     * If the save period is set to 0, then the session is idled whenever the active request count goes from 1 to 0.
-     * @param idlePeriod the idlePeriod in seconds
-     */
-    public void setIdlePeriod(int idlePeriod)
-    {
-        _idlePeriod = idlePeriod;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
-     * @return the invalidateOnStop
-     */
-    public boolean isInvalidateOnStop()
-    {
-        return _invalidateOnStop;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Preserve sessions when the session manager is stopped otherwise remove them from the DB.
-     * @return the removeOnStop
-     */
-    public boolean isPreserveOnStop()
-    {
-        return _preserveOnStop;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Invalidate sessions when the session manager is stopped otherwise save them to the DB.
-     * @param invalidateOnStop the invalidateOnStop to set
-     */
-    public void setInvalidateOnStop(boolean invalidateOnStop)
-    {
-        _invalidateOnStop = invalidateOnStop;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Preserve sessions when the session manager is stopped otherwise remove them from the DB.
-     * @param preserveOnStop the preserveOnStop to set
-     */
-    public void setPreserveOnStop(boolean preserveOnStop)
-    {
-        _preserveOnStop = preserveOnStop;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Save all attributes of a session or only update the dirty attributes.
-     * @return the saveAllAttributes
-     */
-    public boolean isSaveAllAttributes()
-    {
-        return _saveAllAttributes;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Save all attributes of a session or only update the dirty attributes.
-     * @param saveAllAttributes the saveAllAttributes to set
-     */
-    public void setSaveAllAttributes(boolean saveAllAttributes)
-    {
-        _saveAllAttributes = saveAllAttributes;
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
-    {
-        
-        // Take the old session out of the list of sessions
-        // Change to the new id
-        // Put it back into the list of sessions
-        // Update permanent storage
-
-        synchronized (this)
-        {
-            try
-            {
-                NoSqlSession session = _sessions.remove(oldClusterId);
-                update (session, newClusterId, newNodeId);
-                session.setClusterId(newClusterId);
-                session.setNodeId(newNodeId);
-                _sessions.put(newClusterId, session);
-            }
-            catch (Exception e)
-            {
-                __log.warn(e);
-            }
-        }
-        super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
-    }
-
-    
-    /* ------------------------------------------------------------ */
-    abstract protected NoSqlSession loadSession(String clusterId);
-    
-    /* ------------------------------------------------------------ */
-    abstract protected Object save(NoSqlSession session,Object version, boolean activateAfterSave);
-
-    /* ------------------------------------------------------------ */
-    abstract protected Object refresh(NoSqlSession session, Object version);
-
-    /* ------------------------------------------------------------ */
-    abstract protected boolean remove(NoSqlSession session);
-
-    /* ------------------------------------------------------------ */
-    abstract protected void update(NoSqlSession session, String newClusterId, String newNodeId) throws Exception;
-    
-}
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
new file mode 100644
index 0000000..d977c06
--- /dev/null
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java
@@ -0,0 +1,643 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.nosql.mongodb;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
+import org.eclipse.jetty.server.session.SessionData;
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+import com.mongodb.WriteConcern;
+import com.mongodb.WriteResult;
+
+/**
+ * MongoSessionDataStore
+ *
+ *  The document model is an outer object that contains the elements:
+ * <ul>
+ *  <li>"id"      : session_id </li>
+ *  <li>"created" : create_time </li>
+ *  <li>"accessed": last_access_time </li>
+ *  <li>"maxIdle" : max_idle_time setting as session was created </li>
+ *  <li>"expiry"  : time at which session should expire </li>
+ *  <li>"valid"   : session_valid </li>
+ *  <li>"context" : a nested object containing 1 nested object per context for which the session id is in use
+ * </ul>
+ * Each of the nested objects inside the "context" element contains:
+ * <ul>
+ *  <li>unique_context_name : nested object containing name:value pairs of the session attributes for that context</li>
+ * </ul>
+ * <p>
+ * One of the name:value attribute pairs will always be the special attribute "__metadata__". The value 
+ * is an object representing a version counter which is incremented every time the attributes change.
+ * </p>
+ * <p>
+ * For example:
+ * <pre>
+ * { "_id"       : ObjectId("52845534a40b66410f228f23"), 
+ *    "accessed" :  NumberLong("1384818548903"), 
+ *    "maxIdle"  : 1,
+ *    "context"  : { "::_contextA" : { "A"            : "A", 
+ *                                     "__metadata__" : { "version" : NumberLong(2) } 
+ *                                   },
+ *                   "::_contextB" : { "B"            : "B", 
+ *                                     "__metadata__" : { "version" : NumberLong(1) } 
+ *                                   } 
+ *                 }, 
+ *    "created"  : NumberLong("1384818548903"),
+ *    "expiry"   : NumberLong("1384818549903"),
+ *    "id"       : "w01ijx2vnalgv1sqrpjwuirprp7", 
+ *    "valid"    : true 
+ * }
+ * </pre>
+ * <p>
+ * In MongoDB, the nesting level is indicated by "." separators for the key name. Thus to
+ * interact with a session attribute, the key is composed of:
+ * <code>"context".unique_context_name.attribute_name</code>
+ *  Eg  <code>"context"."::/contextA"."A"</code>
+ */
+public class MongoSessionDataStore extends NoSqlSessionDataStore
+{
+    
+    private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    
+    /**
+     * Special attribute for a session that is context-specific
+     */
+    private final static String __METADATA = "__metadata__";
+
+    /**
+     * Name of nested document field containing 1 sub document per context for which the session id is in use
+     */
+    private final static String __CONTEXT = "context";   
+    
+    /**
+     * Special attribute per session per context, incremented each time attributes are modified
+     */
+    public final static String __VERSION = __METADATA + ".version";
+    
+    /**
+     * Last access time of session
+     */
+    public final static String __ACCESSED = "accessed";
+    
+    /**
+     * Time this session will expire, based on last access time and maxIdle
+     */
+    public final static String __EXPIRY = "expiry";
+    
+    /**
+     * The max idle time of a session (smallest value across all contexts which has a session with the same id)
+     */
+    public final static String __MAX_IDLE = "maxIdle";
+    
+    /**
+     * Time of session creation
+     */
+    private final static String __CREATED = "created";
+    
+    /**
+     * Whether or not session is valid
+     */
+    public final static String __VALID = "valid";
+    
+    /**
+     * Session id
+     */
+    public final static String __ID = "id";
+    
+    
+    
+    /**
+     * Utility value of 1 for a session version for this context
+     */
+    private DBObject _version_1;
+    
+    /**
+     * Access to MongoDB
+     */
+    private DBCollection _dbSessions;
+    
+    
+    private long _gracePeriodMs = 1000L * 60 * 60; //default grace period is 1hr
+    
+    public void setDBCollection (DBCollection collection)
+    {
+        _dbSessions = collection;
+    }
+    
+    
+    /**
+     * @return
+     */
+    public DBCollection getDBCollection ()
+    {
+        return _dbSessions;
+    }
+    
+    /**
+     * @return
+     */
+    public int getGracePeriodSec ()
+    {
+        return (int)(_gracePeriodMs == 0L? 0 : _gracePeriodMs/1000L);
+    }
+    
+    /**
+     * @param sec
+     */
+    public void setGracePeriodSec (int sec)
+    {
+        if (sec < 0)
+            _gracePeriodMs = 0;
+        else
+            _gracePeriodMs = sec * 1000L;
+    }
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {
+        final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        Runnable r = new Runnable()
+        {
+            public void run ()
+            {
+                try
+                {
+                    DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
+
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("id={} loaded={}", id, sessionDocument);
+                    
+                    if (sessionDocument == null)
+                        return;
+
+                    Boolean valid = (Boolean)sessionDocument.get(__VALID);   
+
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("id={} valid={}", id, valid);
+                    if (valid == null || !valid)
+                        return;
+
+
+                    Object version = getNestedValue(sessionDocument, getContextSubfield(__VERSION));
+
+                    Long created = (Long)sessionDocument.get(__CREATED);
+                    Long accessed = (Long)sessionDocument.get(__ACCESSED);
+                    Long maxInactive = (Long)sessionDocument.get(__MAX_IDLE);
+                    Long expiry = (Long)sessionDocument.get(__EXPIRY);
+
+                    NoSqlSessionData data = null;
+
+                    // get the session for the context
+                    DBObject sessionSubDocumentForContext = (DBObject)getNestedValue(sessionDocument,getContextField());
+
+                    if (LOG.isDebugEnabled()) LOG.debug("attrs {}", sessionSubDocumentForContext);
+
+                    if (sessionSubDocumentForContext != null)
+                    {
+                        if (LOG.isDebugEnabled())
+                            LOG.debug("Session {} present for context {}", id, _context);
+
+                        //only load a session if it exists for this context
+                        data = (NoSqlSessionData)newSessionData(id, created, accessed, accessed, maxInactive);
+                        data.setVersion(version);
+                        data.setExpiry(expiry);
+                        data.setContextPath(_context.getCanonicalContextPath());
+                        data.setVhost(_context.getVhost());
+
+                        HashMap<String, Object> attributes = new HashMap<>();
+                        for (String name : sessionSubDocumentForContext.keySet())
+                        {
+                            //skip special metadata attribute which is not one of the actual session attributes
+                            if ( __METADATA.equals(name) )
+                                continue;         
+                            String attr = decodeName(name);
+                            Object value = decodeValue(sessionSubDocumentForContext.get(name));
+                            attributes.put(attr,value);
+                        }
+
+                        data.putAllAttributes(attributes);
+                    }
+                    else
+                    {
+                        if (LOG.isDebugEnabled())
+                            LOG.debug("Session  {} not present for context {}", id, _context);        
+                    }
+
+                    reference.set(data);
+                }
+                catch (Exception e)
+                {
+                    exception.set(e);
+                }
+            }
+        };
+        
+        _context.run(r);
+        
+        if (exception.get() != null)
+            throw exception.get();
+        
+        return reference.get();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("Remove:session {} for context ",id, _context);
+
+        /*
+         * Check if the session exists and if it does remove the context
+         * associated with this session
+         */
+        BasicDBObject mongoKey = new BasicDBObject(__ID, id);
+        
+        DBObject sessionDocument = _dbSessions.findOne(mongoKey,_version_1);
+
+        if (sessionDocument != null)
+        {
+            DBObject c = (DBObject)getNestedValue(sessionDocument, __CONTEXT);
+            if (c == null)
+            {
+                //delete whole doc
+                _dbSessions.remove(mongoKey);
+                return false;
+            }
+
+            Set<String> contexts = c.keySet();
+            if (contexts.isEmpty())
+            {
+                //delete whole doc
+                _dbSessions.remove(mongoKey);
+                return false;
+            }
+
+            if (contexts.size() == 1 && contexts.iterator().next().equals(getCanonicalContextId()))
+            {
+                //delete whole doc
+                 _dbSessions.remove(mongoKey);
+                return true;
+            }
+            
+            //just remove entry for my context
+            BasicDBObject remove = new BasicDBObject();
+            BasicDBObject unsets = new BasicDBObject();
+            unsets.put(getContextField(),1);
+            remove.put("$unset",unsets);
+            _dbSessions.update(mongoKey,remove,false,false,WriteConcern.SAFE);
+            
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+        
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+        long upperBound = System.currentTimeMillis();
+        Set<String> expiredSessions = new HashSet<>();
+        
+        //firstly ask mongo to verify if these candidate ids have expired
+        BasicDBObject query = new BasicDBObject();     
+        query.put(__ID,new BasicDBObject("$in", candidates));
+        query.put(__EXPIRY, new BasicDBObject("$gt", 0));
+        query.put(__EXPIRY, new BasicDBObject("$lt", upperBound));   
+
+        DBCursor verifiedExpiredSessions = null;
+        try  
+        {
+            verifiedExpiredSessions = _dbSessions.find(query, new BasicDBObject(__ID, 1));
+            for ( DBObject session : verifiedExpiredSessions )  
+            {
+                String id = (String)session.get(__ID);
+                if (LOG.isDebugEnabled()) LOG.debug("{} Mongo confirmed expired session {}", _context,id);
+                expiredSessions.add(id);
+            }            
+        }
+        finally
+        {
+            if (verifiedExpiredSessions != null) verifiedExpiredSessions.close();
+        }
+
+
+        //now ask mongo to find sessions that expired a while ago    
+        upperBound = upperBound - (3 * _gracePeriodMs);
+        query.clear();
+        query.put(__EXPIRY, new BasicDBObject("$gt", 0));
+        query.put(__EXPIRY, new BasicDBObject("$lt", upperBound));
+
+        DBCursor oldExpiredSessions = null;
+        try
+        {
+            oldExpiredSessions = _dbSessions.find(query, new BasicDBObject(__ID, 1));
+            for (DBObject session : oldExpiredSessions)
+            {
+                String id = (String)session.get(__ID);
+                if (LOG.isDebugEnabled()) LOG.debug("{} Mongo found old expired session {}", _context, id);
+                expiredSessions.add(id);
+            }
+
+        }
+        finally
+        {
+            oldExpiredSessions.close();
+        }
+        
+        return expiredSessions;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData, boolean)
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        NoSqlSessionData nsqd = (NoSqlSessionData)data;
+        
+        // Form query for upsert
+        BasicDBObject key = new BasicDBObject(__ID, id);
+
+        // Form updates
+        BasicDBObject update = new BasicDBObject();
+        boolean upsert = false;
+        BasicDBObject sets = new BasicDBObject();
+        BasicDBObject unsets = new BasicDBObject();
+        
+        Object version = ((NoSqlSessionData)data).getVersion();
+        
+        // New session
+        if (isNew)
+        {
+            upsert = true;
+            version = new Long(1);
+            sets.put(__CREATED,nsqd.getCreated());
+            sets.put(__VALID,true);
+
+            sets.put(getContextSubfield(__VERSION),version);
+            sets.put(__MAX_IDLE, nsqd.getMaxInactiveMs());
+            sets.put(__EXPIRY, nsqd.getExpiry());
+            nsqd.setVersion(version);
+        }
+        else
+        {
+            version = new Long(((Number)version).longValue() + 1);
+            nsqd.setVersion(version);
+            update.put("$inc",_version_1); 
+            //if max idle time and/or expiry is smaller for this context, then choose that for the whole session doc
+            BasicDBObject fields = new BasicDBObject();
+            fields.append(__MAX_IDLE, true);
+            fields.append(__EXPIRY, true);
+            DBObject o = _dbSessions.findOne(new BasicDBObject("id", id), fields);
+            if (o != null)
+            {
+                Long currentMaxIdle = (Long)o.get(__MAX_IDLE);
+                Long currentExpiry = (Long)o.get(__EXPIRY);
+                if (currentMaxIdle != null && nsqd.getMaxInactiveMs() > 0 && nsqd.getMaxInactiveMs() < currentMaxIdle)
+                    sets.put(__MAX_IDLE, nsqd.getMaxInactiveMs());
+                if (currentExpiry != null && nsqd.getExpiry() > 0 && nsqd.getExpiry() != currentExpiry)
+                    sets.put(__EXPIRY, nsqd.getExpiry());
+            }
+            else
+                LOG.warn("Session {} not found, can't update", id);
+        }
+
+        sets.put(__ACCESSED, nsqd.getAccessed());
+
+        Set<String> names = nsqd.takeDirtyAttributes();
+
+        if (isNew)
+        {
+            names.addAll(nsqd.getAllAttributeNames()); // note dirty may include removed names
+        }
+
+
+        for (String name : names)
+        {
+
+            Object value = data.getAttribute(name);
+            if (value == null)
+                unsets.put(getContextField() + "." + encodeName(name),1);
+            else
+                sets.put(getContextField() + "." + encodeName(name),encodeName(value));
+        }
+
+        // Do the upsert
+        if (!sets.isEmpty())
+            update.put("$set",sets);
+        if (!unsets.isEmpty())
+            update.put("$unset",unsets);
+
+        _dbSessions.update(key,update,upsert,false,WriteConcern.SAFE);
+
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("Save:db.sessions.update( {}, {} )", key, update); 
+    }
+
+
+    
+    
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_dbSessions == null)
+            throw new IllegalStateException("DBCollection not set");
+        
+        _version_1 = new BasicDBObject(getContextSubfield(__VERSION),1);
+        
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        // TODO Auto-generated method stub
+        super.doStop();
+    }
+
+    /*------------------------------------------------------------ */
+    private String getContextField ()
+    {
+        return __CONTEXT + "." + getCanonicalContextId();
+    }
+    
+   
+    private String getCanonicalContextId ()
+    {
+        return canonicalizeVHost(_context.getVhost()) + ":" + _context.getCanonicalContextPath();
+    }
+    
+    private String canonicalizeVHost (String vhost)
+    {
+        if (vhost == null)
+            return "";
+        
+        return vhost.replace('.', '_');
+    }
+  
+    
+    private String getContextSubfield (String attr)
+    {
+        return getContextField () +"."+ attr;
+    }
+    
+
+    /*------------------------------------------------------------ */
+    protected Object decodeValue(final Object valueToDecode) throws IOException, ClassNotFoundException
+    {
+        if (valueToDecode == null || valueToDecode instanceof Number || valueToDecode instanceof String || valueToDecode instanceof Boolean || valueToDecode instanceof Date)
+        {
+            return valueToDecode;
+        }
+        else if (valueToDecode instanceof byte[])
+        {
+            final byte[] decodeObject = (byte[])valueToDecode;
+            final ByteArrayInputStream bais = new ByteArrayInputStream(decodeObject);
+            final ClassLoadingObjectInputStream objectInputStream = new ClassLoadingObjectInputStream(bais);
+            return objectInputStream.readUnshared();
+        }
+        else if (valueToDecode instanceof DBObject)
+        {
+            Map<String, Object> map = new HashMap<String, Object>();
+            for (String name : ((DBObject)valueToDecode).keySet())
+            {
+                String attr = decodeName(name);
+                map.put(attr,decodeValue(((DBObject)valueToDecode).get(name)));
+            }
+            return map;
+        }
+        else
+        {
+            throw new IllegalStateException(valueToDecode.getClass().toString());
+        }
+    }
+    /*------------------------------------------------------------ */
+    protected String decodeName(String name)
+    {
+        return name.replace("%2E",".").replace("%25","%");
+    }
+    
+
+    /*------------------------------------------------------------ */
+    protected String encodeName(String name)
+    {
+        return name.replace("%","%25").replace(".","%2E");
+    }
+
+
+    /*------------------------------------------------------------ */
+    protected Object encodeName(Object value) throws IOException
+    {
+        if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date)
+        {
+            return value;
+        }
+        else if (value.getClass().equals(HashMap.class))
+        {
+            BasicDBObject o = new BasicDBObject();
+            for (Map.Entry<?, ?> entry : ((Map<?, ?>)value).entrySet())
+            {
+                if (!(entry.getKey() instanceof String))
+                {
+                    o = null;
+                    break;
+                }
+                o.append(encodeName(entry.getKey().toString()),encodeName(entry.getValue()));
+            }
+
+            if (o != null)
+                return o;
+        }
+        
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bout);
+        out.reset();
+        out.writeUnshared(value);
+        out.flush();
+        return bout.toByteArray();
+    }
+    
+    /*------------------------------------------------------------ */
+    /**
+     * Dig through a given dbObject for the nested value
+     */
+    private Object getNestedValue(DBObject dbObject, String nestedKey)
+    {
+        String[] keyChain = nestedKey.split("\\.");
+
+        DBObject temp = dbObject;
+
+        for (int i = 0; i < keyChain.length - 1; ++i)
+        {
+            temp = (DBObject)temp.get(keyChain[i]);
+
+            if ( temp == null )
+            {
+                return null;
+            }
+        }
+
+        return temp.get(keyChain[keyChain.length - 1]);
+    }
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+     */
+    @Override
+    public boolean isPassivating()
+    {
+        return true;
+    }
+
+}
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
index 894a3fd..9113d9c 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java
@@ -20,93 +20,40 @@
 
 
 import java.net.UnknownHostException;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
 
-import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.server.session.AbstractSessionIdManager;
-import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.util.ConcurrentHashSet;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
 
 import com.mongodb.BasicDBObject;
 import com.mongodb.BasicDBObjectBuilder;
 import com.mongodb.DBCollection;
-import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
 import com.mongodb.Mongo;
 import com.mongodb.MongoException;
 
 /**
- * Based partially on the JDBCSessionIdManager.
- * <p>
- * Theory is that we really only need the session id manager for the local 
- * instance so we have something to scavenge on, namely the list of known ids
- * <p>
- * This class has a timer that runs a periodic scavenger thread to query
- *  for all id's known to this node whose precalculated expiry time has passed.
- * <p>
- * These found sessions are then run through the invalidateAll(id) method that 
- * is a bit hinky but is supposed to notify all handlers this id is now DOA and 
- * ought to be cleaned up.  this ought to result in a save operation on the session
- * that will change the valid field to false (this conjecture is unvalidated atm)
+ * Manager of session ids based on sessions stored in Mongo.
+ * 
  */
 public class MongoSessionIdManager extends AbstractSessionIdManager
 {
-    private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
+    private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
 
-    final static DBObject __version_1 = new BasicDBObject(MongoSessionManager.__VERSION,1);
-    final static DBObject __valid_false = new BasicDBObject(MongoSessionManager.__VALID,false);
-    final static DBObject __valid_true = new BasicDBObject(MongoSessionManager.__VALID,true);
+    final static DBObject __version_1 = new BasicDBObject(MongoSessionDataStore.__VERSION,1);
+    final static DBObject __valid_false = new BasicDBObject(MongoSessionDataStore.__VALID,false);
+    final static DBObject __valid_true = new BasicDBObject(MongoSessionDataStore.__VALID,true);
+    final static DBObject __expiry = new BasicDBObject(MongoSessionDataStore.__EXPIRY, 1);
 
-    final static long __defaultScavengePeriod = 30 * 60 * 1000; // every 30 minutes
-   
     
     final DBCollection _sessions;
-    protected Server _server;
-    private Scheduler _scheduler;
-    private boolean _ownScheduler;
-    private Scheduler.Task _scavengerTask;
-    private Scheduler.Task _purgerTask;
- 
-
-    
-    private long _scavengePeriod = __defaultScavengePeriod;
-    
-
-    /** 
-     * purge process is enabled by default
-     */
-    private boolean _purge = true;
-
-    /**
-     * purge process would run daily by default
-     */
-    private long _purgeDelay = 24 * 60 * 60 * 1000; // every day
-    
-    /**
-     * how long do you want to persist sessions that are no longer
-     * valid before removing them completely
-     */
-    private long _purgeInvalidAge = 24 * 60 * 60 * 1000; // default 1 day
-
-    /**
-     * how long do you want to leave sessions that are still valid before
-     * assuming they are dead and removing them
-     */
-    private long _purgeValidAge = 7 * 24 * 60 * 60 * 1000; // default 1 week
 
     
     /**
@@ -114,57 +61,7 @@
      */
     protected final Set<String> _sessionsIds = new ConcurrentHashSet<>();
 
-    /**
-     * The maximum number of items to return from a purge query.
-     */
-    private int _purgeLimit = 0;
-
-    private int _scavengeBlockSize;
-    
-    
-    /**
-     * Scavenger
-     *
-     */
-    protected class Scavenger implements Runnable
-    {
-        @Override
-        public void run()
-        {
-            try
-            {
-                scavenge();
-            }
-            finally
-            {
-                if (_scheduler != null && _scheduler.isRunning())
-                    _scavengerTask = _scheduler.schedule(this, _scavengePeriod, TimeUnit.MILLISECONDS);
-            }
-        } 
-    }
-    
-    
-    /**
-     * Purger
-     *
-     */
-    protected class Purger implements Runnable
-    {
-        @Override
-        public void run()
-        {
-            try
-            {
-                purge();
-            }
-            finally
-            {
-                if (_scheduler != null && _scheduler.isRunning())
-                    _purgerTask = _scheduler.schedule(this, _purgeDelay, TimeUnit.MILLISECONDS);
-            }
-        }
-    }
-    
+   
     
     
 
@@ -177,9 +74,8 @@
     /* ------------------------------------------------------------ */
     public MongoSessionIdManager(Server server, DBCollection sessions)
     {
-        super(new Random());
+        super(server, new Random());
         
-        _server = server;
         _sessions = sessions;
 
         _sessions.ensureIndex(
@@ -193,187 +89,10 @@
         // so that we can take advantage of index prefixes
         // http://docs.mongodb.org/manual/core/index-compound/#compound-index-prefix
         _sessions.ensureIndex(
-                BasicDBObjectBuilder.start().add(MongoSessionManager.__VALID, 1).add(MongoSessionManager.__ACCESSED, 1).get(),
+                BasicDBObjectBuilder.start().add(MongoSessionDataStore.__VALID, 1).add(MongoSessionDataStore.__ACCESSED, 1).get(),
                 BasicDBObjectBuilder.start().add("sparse", false).add("background", true).get());
     }
  
-    /* ------------------------------------------------------------ */
-    /**
-     * Scavenge is a process that periodically checks the tracked session
-     * ids of this given instance of the session id manager to see if they 
-     * are past the point of expiration.
-     */
-    protected void scavenge()
-    {
-        long now = System.currentTimeMillis();
-        __log.debug(getWorkerName()+":SessionIdManager:scavenge:at {}", now);        
-        /*
-         * run a query returning results that:
-         *  - are in the known list of sessionIds
-         *  - the expiry time has passed
-         *  
-         *  we limit the query to return just the __ID so we are not sucking back full sessions
-         *  
-         *  break scavenge query into blocks for faster mongo queries
-         */
-        Set<String> block = new HashSet<String>();
-            
-        Iterator<String> itor = _sessionsIds.iterator();
-        while (itor.hasNext())
-        {
-            block.add(itor.next());
-            if ((_scavengeBlockSize > 0) && (block.size() == _scavengeBlockSize))
-            {
-                //got a block
-                scavengeBlock (now, block);
-                //reset for next run
-                block.clear();
-            }
-        }
-        
-        //non evenly divisble block size, or doing it all at once
-        if (!block.isEmpty())
-            scavengeBlock(now, block);
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Check a block of session ids for expiry and thus scavenge.
-     * 
-     * @param atTime purge at time
-     * @param ids set of session ids
-     */
-    protected void scavengeBlock (long atTime, Set<String> ids)
-    {
-        if (ids == null)
-            return;
-        
-        BasicDBObject query = new BasicDBObject();     
-        query.put(MongoSessionManager.__ID,new BasicDBObject("$in", ids ));
-        query.put(MongoSessionManager.__EXPIRY, new BasicDBObject("$gt", 0));
-        query.put(MongoSessionManager.__EXPIRY, new BasicDBObject("$lt", atTime));   
-            
-        DBCursor checkSessions = _sessions.find(query, new BasicDBObject(MongoSessionManager.__ID, 1));
-                        
-        for ( DBObject session : checkSessions )
-        {             
-            __log.debug(getWorkerName()+":SessionIdManager:scavenge: {} expiring session {}", atTime,(String)session.get(MongoSessionManager.__ID));
-            expireAll((String)session.get(MongoSessionManager.__ID));
-        }            
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * ScavengeFully will expire all sessions. In most circumstances
-     * you should never need to call this method.
-     * 
-     * <b>USE WITH CAUTION</b>
-     */
-    protected void scavengeFully()
-    {        
-        __log.debug("SessionIdManager:scavengeFully");
-
-        DBCursor checkSessions = _sessions.find();
-
-        for (DBObject session : checkSessions)
-        {
-            expireAll((String)session.get(MongoSessionManager.__ID));
-        }
-
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Purge is a process that cleans the mongodb cluster of old sessions that are no
-     * longer valid.
-     * 
-     * There are two checks being done here:
-     * 
-     *  - if the accessed time is older than the current time minus the purge invalid age
-     *    and it is no longer valid then remove that session
-     *  - if the accessed time is older then the current time minus the purge valid age
-     *    then we consider this a lost record and remove it
-     *    
-     *  NOTE: if your system supports long lived sessions then the purge valid age should be
-     *  set to zero so the check is skipped.
-     *  
-     *  The second check was added to catch sessions that were being managed on machines 
-     *  that might have crashed without marking their sessions as 'valid=false'
-     */
-    protected void purge()
-    {
-        __log.debug("PURGING");
-        BasicDBObject invalidQuery = new BasicDBObject();
-
-        invalidQuery.put(MongoSessionManager.__VALID, false);
-        invalidQuery.put(MongoSessionManager.__ACCESSED, new BasicDBObject("$lt",System.currentTimeMillis() - _purgeInvalidAge));
-        
-        DBCursor oldSessions = _sessions.find(invalidQuery, new BasicDBObject(MongoSessionManager.__ID, 1));
-
-        if (_purgeLimit > 0)
-        {
-            oldSessions.limit(_purgeLimit);
-        }
-
-        for (DBObject session : oldSessions)
-        {
-            String id = (String)session.get("id");
-            
-            __log.debug("MongoSessionIdManager:purging invalid session {}", id);
-            
-            _sessions.remove(session);
-        }
-
-        if (_purgeValidAge != 0)
-        {
-            BasicDBObject validQuery = new BasicDBObject();
-
-            validQuery.put(MongoSessionManager.__VALID, true);
-            validQuery.put(MongoSessionManager.__ACCESSED,new BasicDBObject("$lt",System.currentTimeMillis() - _purgeValidAge));
-
-            oldSessions = _sessions.find(validQuery,new BasicDBObject(MongoSessionManager.__ID,1));
-
-            if (_purgeLimit > 0)
-            {
-                oldSessions.limit(_purgeLimit);
-            }
-
-            for (DBObject session : oldSessions)
-            {
-                String id = (String)session.get(MongoSessionManager.__ID);
-
-                __log.debug("MongoSessionIdManager:purging valid session {}", id);
-
-                _sessions.remove(session);
-            }
-        }
-
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Purge is a process that cleans the mongodb cluster of old sessions that are no
-     * longer valid.
-     * 
-     */
-    protected void purgeFully()
-    {
-        BasicDBObject invalidQuery = new BasicDBObject();
-        invalidQuery.put(MongoSessionManager.__VALID, false);
-        
-        DBCursor oldSessions = _sessions.find(invalidQuery, new BasicDBObject(MongoSessionManager.__ID, 1));
-        
-        for (DBObject session : oldSessions)
-        {
-            String id = (String)session.get(MongoSessionManager.__ID);
-            
-            __log.debug("MongoSessionIdManager:purging invalid session {}", id);
-            
-            _sessions.remove(session);
-        }
-
-    }
     
     
     /* ------------------------------------------------------------ */
@@ -382,192 +101,20 @@
         return _sessions;
     }
     
-    
-    /* ------------------------------------------------------------ */
-    public boolean isPurgeEnabled()
-    {
-        return _purge;
-    }
-    
-    /* ------------------------------------------------------------ */
-    public void setPurge(boolean purge)
-    {
-        this._purge = purge;
-    }
-
-
-    /* ------------------------------------------------------------ */
-    /** 
-     * The period in seconds between scavenge checks.
-     * 
-     * @param scavengePeriod the scavenge period in seconds
-     */
-    public void setScavengePeriod(long scavengePeriod)
-    {
-        if (scavengePeriod <= 0)
-            _scavengePeriod = __defaultScavengePeriod;
-        else
-            _scavengePeriod = TimeUnit.SECONDS.toMillis(scavengePeriod);
-    }
-
-    /* ------------------------------------------------------------ */
-    /** When scavenging, the max number of session ids in the query.
-     * 
-     * @param size the scavenge block size
-     */
-    public void setScavengeBlockSize (int size)
-    {
-        _scavengeBlockSize = size;
-    }
-
-    /* ------------------------------------------------------------ */
-    public int getScavengeBlockSize ()
-    {
-        return _scavengeBlockSize;
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * The maximum number of items to return from a purge query. If &lt;= 0 there is no limit. Defaults to 0
-     * 
-     * @param purgeLimit the purge limit 
-     */
-    public void setPurgeLimit(int purgeLimit)
-    {
-        _purgeLimit = purgeLimit;
-    }
-
-    /* ------------------------------------------------------------ */
-    public int getPurgeLimit()
-    {
-        return _purgeLimit;
-    }
-
-
-
-    /* ------------------------------------------------------------ */
-    public void setPurgeDelay(long purgeDelay)
-    {
-        if ( isRunning() )
-        {
-            throw new IllegalStateException();
-        }
-        
-        this._purgeDelay = purgeDelay;
-    }
- 
-    /* ------------------------------------------------------------ */
-    public long getPurgeInvalidAge()
-    {
-        return _purgeInvalidAge;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * sets how old a session is to be persisted past the point it is
-     * no longer valid
-     * @param purgeValidAge the purge valid age
-     */
-    public void setPurgeInvalidAge(long purgeValidAge)
-    {
-        this._purgeInvalidAge = purgeValidAge;
-    } 
-    
-    /* ------------------------------------------------------------ */
-    public long getPurgeValidAge()
-    {
-        return _purgeValidAge;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * sets how old a session is to be persist past the point it is 
-     * considered no longer viable and should be removed
-     * 
-     * NOTE: set this value to 0 to disable purging of valid sessions
-     * @param purgeValidAge the purge valid age
-     */
-    public void setPurgeValidAge(long purgeValidAge)
-    {
-        this._purgeValidAge = purgeValidAge;
-    } 
 
     /* ------------------------------------------------------------ */
     @Override
     protected void doStart() throws Exception
     {
-        __log.debug("MongoSessionIdManager:starting");
-
-
-        synchronized (this)
-        {
-            //try and use a common scheduler, fallback to own
-            _scheduler =_server.getBean(Scheduler.class);
-            if (_scheduler == null)
-            {
-                _scheduler = new ScheduledExecutorScheduler();
-                _ownScheduler = true;
-                _scheduler.start();
-            }   
-            else if (!_scheduler.isStarted())
-                throw new IllegalStateException("Shared scheduler not started");
-            
-
-            //setup the scavenger thread
-            if (_scavengePeriod > 0)
-            {
-                if (_scavengerTask != null)
-                {
-                    _scavengerTask.cancel();
-                    _scavengerTask = null;
-                }
-
-                _scavengerTask = _scheduler.schedule(new Scavenger(), _scavengePeriod, TimeUnit.MILLISECONDS);
-            }
-            else if (__log.isDebugEnabled())
-                __log.debug("Scavenger disabled");
-
-
-            //if purging is enabled, setup the purge thread
-            if ( _purge )
-            { 
-                if (_purgerTask != null)
-                {
-                    _purgerTask.cancel();
-                    _purgerTask = null;
-                }
-                _purgerTask = _scheduler.schedule(new Purger(), _purgeDelay, TimeUnit.MILLISECONDS);
-            }
-            else if (__log.isDebugEnabled())
-                __log.debug("Purger disabled");
-        }
+        if (LOG.isDebugEnabled()) LOG.debug("MongoSessionIdManager:starting");
+        super.doStart();
     }
 
     /* ------------------------------------------------------------ */
     @Override
     protected void doStop() throws Exception
     {
-        synchronized (this)
-        {
-            if (_scavengerTask != null)
-            {
-                _scavengerTask.cancel();
-                _scavengerTask = null;
-            }
- 
-            if (_purgerTask != null)
-            {
-                _purgerTask.cancel();
-                _purgerTask = null;
-            }
-            
-            if (_ownScheduler && _scheduler != null)
-            {
-                _scheduler.stop();
-                _scheduler = null;
-            }
-        }
+        if (LOG.isDebugEnabled()) LOG.debug("MongoSessionIdManager:stopping");
         super.doStop();
     }
 
@@ -576,20 +123,26 @@
      * Searches database to find if the session id known to mongo, and is it valid
      */
     @Override
-    public boolean idInUse(String sessionId)
+    public boolean isIdInUse(String sessionId)
     {        
         /*
-         * optimize this query to only return the valid variable
+         * optimize this query to only return the valid and expiry
          */
-        DBObject o = _sessions.findOne(new BasicDBObject("id",sessionId), __valid_true);
+        DBObject fields = new BasicDBObject();
+        fields.put(MongoSessionDataStore.__VALID, new Long(1));
+        fields.put(MongoSessionDataStore.__EXPIRY, new Long(1));
+        
+        DBObject o = _sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,sessionId), fields);
         
         if ( o != null )
         {                    
-            Boolean valid = (Boolean)o.get(MongoSessionManager.__VALID);
+            Boolean valid = (Boolean)o.get(MongoSessionDataStore.__VALID);
             if ( valid == null )
-            {
+                return false;            
+            
+            Long expiry = (Long)o.get(MongoSessionDataStore.__EXPIRY);
+            if (expiry < System.currentTimeMillis())
                 return false;
-            }            
             
             return valid;
         }
@@ -599,119 +152,27 @@
 
     /* ------------------------------------------------------------ */
     @Override
-    public void addSession(HttpSession session)
+    public void useId(Session session)
     {
         if (session == null)
-        {
             return;
-        }
         
         /*
          * already a part of the index in mongo...
          */
         
-        __log.debug("MongoSessionIdManager:addSession {}", session.getId());
-        
-        _sessionsIds.add(session.getId());
-        
+        LOG.debug("MongoSessionIdManager:addSession {}", session.getId());
     }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void removeSession(HttpSession session)
-    {
-        if (session == null)
-        {
-            return;
-        }
-        
-        _sessionsIds.remove(session.getId());
-    }
-
-    /* ------------------------------------------------------------ */
-    /** Remove the session id from the list of in-use sessions.
-     * Inform all other known contexts that sessions with the same id should be
-     * invalidated.
-     * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
-     */
-    @Override
-    public void invalidateAll(String sessionId)
-    {
-        _sessionsIds.remove(sessionId);
-            
-        //tell all contexts that may have a session object with this id to
-        //get rid of them
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null) 
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof MongoSessionManager)
-                {
-                    ((MongoSessionManager)manager).invalidateSession(sessionId);
-                }
-            }
-        }
-    }      
  
 
     /* ------------------------------------------------------------ */
-    /**
-     * Expire this session for all contexts that are sharing the session 
-     * id.
-     * @param sessionId the session id
-     */
-    public void expireAll (String sessionId)
-    {
-        _sessionsIds.remove(sessionId);
-            
-            
-        //tell all contexts that may have a session object with this id to
-        //get rid of them
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null) 
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof MongoSessionManager)
-                {
-                    ((MongoSessionManager)manager).expire(sessionId);
-                }
-            }
-        }      
-    }
-    
-    /* ------------------------------------------------------------ */
     @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
+    public boolean removeId(String id)
     {
-        //generate a new id
-        String newClusterId = newSessionId(request.hashCode());
-
-        _sessionsIds.remove(oldClusterId);//remove the old one from the list
-        _sessionsIds.add(newClusterId); //add in the new session id to the list
-
-        //tell all contexts to update the id 
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null) 
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-
-                if (manager != null && manager instanceof MongoSessionManager)
-                {
-                    ((MongoSessionManager)manager).renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
-                }
-            }
-        }
+       //The corresponding session document will be marked as expired or invalid?
+        return true; //can't distinguish first remove vs subsequent removes
     }
 
+  
+
 }
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java
index 8c44e9f..a4e8a37 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java
@@ -18,31 +18,20 @@
 
 package org.eclipse.jetty.nosql.mongodb;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.net.UnknownHostException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
 
-import org.eclipse.jetty.nosql.NoSqlSession;
-import org.eclipse.jetty.nosql.NoSqlSessionManager;
 import org.eclipse.jetty.server.SessionIdManager;
+import org.eclipse.jetty.server.session.AbstractSessionStore;
+import org.eclipse.jetty.server.session.MemorySessionStore;
+import org.eclipse.jetty.server.session.SessionDataStore;
+import org.eclipse.jetty.server.session.SessionManager;
 import org.eclipse.jetty.util.annotation.ManagedAttribute;
 import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.annotation.ManagedOperation;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 
-import com.mongodb.BasicDBObject;
 import com.mongodb.DBCollection;
-import com.mongodb.DBObject;
 import com.mongodb.MongoException;
-import com.mongodb.WriteConcern;
 
 
 /**
@@ -93,71 +82,10 @@
  *  Eg  <code>"context"."::/contextA"."A"</code>
  */
 @ManagedObject("Mongo Session Manager")
-public class MongoSessionManager extends NoSqlSessionManager
+public class MongoSessionManager extends SessionManager
 {
-    private static final Logger LOG = Log.getLogger(MongoSessionManager.class);
-  
-    private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
-   
-    /*
-     * strings used as keys or parts of keys in mongo
-     */
-    /**
-     * Special attribute for a session that is context-specific
-     */
-    private final static String __METADATA = "__metadata__";
+    private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
 
-    
-    /**
-     * Session id
-     */
-    public final static String __ID = "id";
-    
-    /**
-     * Time of session creation
-     */
-    private final static String __CREATED = "created";
-    
-    /**
-     * Whether or not session is valid
-     */
-    public final static String __VALID = "valid";
-    
-    /**
-     * Time at which session was invalidated
-     */
-    public final static String __INVALIDATED = "invalidated";
-    
-    /**
-     * Last access time of session
-     */
-    public final static String __ACCESSED = "accessed";
-    
-    /**
-     * Time this session will expire, based on last access time and maxIdle
-     */
-    public final static String __EXPIRY = "expiry";
-    
-    /**
-     * The max idle time of a session (smallest value across all contexts which has a session with the same id)
-     */
-    public final static String __MAX_IDLE = "maxIdle";
-    
-    /**
-     * Name of nested document field containing 1 sub document per context for which the session id is in use
-     */
-    private final static String __CONTEXT = "context";   
-    
-    
-    /**
-     * Special attribute per session per context, incremented each time attributes are modified
-     */
-    public final static String __VERSION = __METADATA + ".version";
-
-    /**
-    * the context id is only set when this class has been started
-    */
-    private String _contextId = null;
 
     
     /**
@@ -166,16 +94,14 @@
     private DBCollection _dbSessions;
     
     
-    /**
-     * Utility value of 1 for a session version for this context
-     */
-    private DBObject _version_1;
+    private MongoSessionDataStore _sessionDataStore;
 
 
     /* ------------------------------------------------------------ */
     public MongoSessionManager() throws UnknownHostException, MongoException
     {
-        
+        _sessionStore = new MemorySessionStore();
+        _sessionDataStore = new MongoSessionDataStore();
     }
     
     
@@ -183,22 +109,10 @@
     /*------------------------------------------------------------ */
     @Override
     public void doStart() throws Exception
-    {
+    {    
+        ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
+        _sessionDataStore.setDBCollection(_dbSessions);
         super.doStart();
-        String[] hosts = getContextHandler().getVirtualHosts();
-
-        if (hosts == null || hosts.length == 0)
-            hosts = new String[]
-            { "::" }; // IPv6 equiv of 0.0.0.0
-
-        String contextPath = getContext().getContextPath();
-        if (contextPath == null || "".equals(contextPath))
-        {
-            contextPath = "*";
-        }
-
-        _contextId = createContextId(hosts,contextPath);
-        _version_1 = new BasicDBObject(getContextAttributeKey(__VERSION),1);
     }
 
     /* ------------------------------------------------------------ */
@@ -214,491 +128,15 @@
         
     }
 
-    /* ------------------------------------------------------------ */
-    @Override
-    protected synchronized Object save(NoSqlSession session, Object version, boolean activateAfterSave)
-    {
-        try
-        {
-            __log.debug("MongoSessionManager:save session {}", session.getClusterId());
-            session.willPassivate();
-
-            // Form query for upsert
-            BasicDBObject key = new BasicDBObject(__ID,session.getClusterId());
-
-            // Form updates
-            BasicDBObject update = new BasicDBObject();
-            boolean upsert = false;
-            BasicDBObject sets = new BasicDBObject();
-            BasicDBObject unsets = new BasicDBObject();
-
-            
-            // handle valid or invalid
-            if (session.isValid())
-            {
-                long expiry = (session.getMaxInactiveInterval() > 0?(session.getAccessed()+(1000L*getMaxInactiveInterval())):0);
-                __log.debug("MongoSessionManager: calculated expiry {} for session {}", expiry, session.getId());
-                
-                // handle new or existing
-                if (version == null)
-                {
-                    // New session
-                    upsert = true;
-                    version = new Long(1);
-                    sets.put(__CREATED,session.getCreationTime());
-                    sets.put(__VALID,true);
-                   
-                    sets.put(getContextAttributeKey(__VERSION),version);
-                    sets.put(__MAX_IDLE, getMaxInactiveInterval());
-                    sets.put(__EXPIRY, expiry);
-                }
-                else
-                {
-                    version = new Long(((Number)version).longValue() + 1);
-                    update.put("$inc",_version_1); 
-                    //if max idle time and/or expiry is smaller for this context, then choose that for the whole session doc
-                    BasicDBObject fields = new BasicDBObject();
-                    fields.append(__MAX_IDLE, true);
-                    fields.append(__EXPIRY, true);
-                    DBObject o = _dbSessions.findOne(new BasicDBObject("id",session.getClusterId()), fields);
-                    if (o != null)
-                    {
-                        Integer currentMaxIdle = (Integer)o.get(__MAX_IDLE);
-                        Long currentExpiry = (Long)o.get(__EXPIRY);
-                        if (currentMaxIdle != null && getMaxInactiveInterval() > 0 && getMaxInactiveInterval() < currentMaxIdle)
-                            sets.put(__MAX_IDLE, getMaxInactiveInterval());
-                        if (currentExpiry != null && expiry > 0 && expiry != currentExpiry)
                         {
-                            sets.put(__EXPIRY, expiry);
                         }
-                    }
-                }
-                
-                sets.put(__ACCESSED,session.getAccessed());
-                Set<String> names = session.takeDirty();
-                if (isSaveAllAttributes() || upsert)
-                {
-                    names.addAll(session.getNames()); // note dirty may include removed names
-                }
-                    
-                for (String name : names)
-                {
-                    Object value = session.getAttribute(name);
-                    if (value == null)
-                        unsets.put(getContextKey() + "." + encodeName(name),1);
-                    else
-                        sets.put(getContextKey() + "." + encodeName(name),encodeName(value));
-                }
-            }
-            else
-            {
-                sets.put(__VALID,false);
-                sets.put(__INVALIDATED, System.currentTimeMillis());
-                unsets.put(getContextKey(),1); 
-            }
-
-            // Do the upsert
-            if (!sets.isEmpty())
-                update.put("$set",sets);
-            if (!unsets.isEmpty())
-                update.put("$unset",unsets);
-
-            _dbSessions.update(key,update,upsert,false,WriteConcern.SAFE);
-
-            if (__log.isDebugEnabled())
-                __log.debug("MongoSessionManager:save:db.sessions.update( {}, {} )", key, update);
-           
-            if (activateAfterSave)
-                session.didActivate();
-
-            return version;
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-        return null;
-    }
-
-    /*------------------------------------------------------------ */
-    @Override
-    protected Object refresh(NoSqlSession session, Object version)
-    {
-        __log.debug("MongoSessionManager:refresh session {}", session.getId());
-
-        // check if our in memory version is the same as what is on the disk
-        if (version != null)
-        {
-            DBObject o = _dbSessions.findOne(new BasicDBObject(__ID,session.getClusterId()),_version_1);
-
-            if (o != null)
-            {
-                Object saved = getNestedValue(o, getContextAttributeKey(__VERSION));
-                
-                if (saved != null && saved.equals(version))
-                {
-                    __log.debug("MongoSessionManager:refresh not needed session {}", session.getId());
-                    return version;
-                }
-                version = saved;
-            }
-        }
-
-        // If we are here, we have to load the object
-        DBObject o = _dbSessions.findOne(new BasicDBObject(__ID,session.getClusterId()));
-
-        // If it doesn't exist, invalidate
-        if (o == null)
-        {
-            __log.debug("MongoSessionManager:refresh:marking session {} invalid, no object", session.getClusterId());
-            session.invalidate();
-            return null;
-        }
-        
-        // If it has been flagged invalid, invalidate
-        Boolean valid = (Boolean)o.get(__VALID);
-        if (valid == null || !valid)
-        {
-            __log.debug("MongoSessionManager:refresh:marking session {} invalid, valid flag {}", session.getClusterId(), valid);
-            session.invalidate();
-            return null;
-        }
-
-        // We need to update the attributes. We will model this as a passivate,
-        // followed by bindings and then activation.
-        session.willPassivate();
-        try
-        {     
-            DBObject attrs = (DBObject)getNestedValue(o,getContextKey());    
-            //if disk version now has no attributes, get rid of them
-            if (attrs == null || attrs.keySet().size() == 0)
-            {
-                session.clearAttributes();
-            }
-            else
-            {
-                //iterate over the names of the attributes on the disk version, updating the value
-                for (String name : attrs.keySet())
-                {
-                    //skip special metadata field which is not one of the session attributes
-                    if (__METADATA.equals(name))
-                        continue;
-
-                    String attr = decodeName(name);
-                    Object value = decodeValue(attrs.get(name));
-
-                    //session does not already contain this attribute, so bind it
-                    if (session.getAttribute(attr) == null)
-                    { 
-                        session.doPutOrRemove(attr,value);
-                        session.bindValue(attr,value);
-                    }
-                    else //session already contains this attribute, update its value
-                    {
-                        session.doPutOrRemove(attr,value);
-                    }
-
-                }
-                // cleanup, remove values from session, that don't exist in data anymore:
-                for (String str : session.getNames())
-                {
-                   if (!attrs.keySet().contains(encodeName(str)))
-                   {
-                        session.doPutOrRemove(str,null);
-                        session.unbindValue(str,session.getAttribute(str));
-                    }
-                }
-            }
-
-            /*
-             * We are refreshing so we should update the last accessed time.
-             */
-            BasicDBObject key = new BasicDBObject(__ID,session.getClusterId());
-            BasicDBObject sets = new BasicDBObject();
-            // Form updates
-            BasicDBObject update = new BasicDBObject();
-            sets.put(__ACCESSED,System.currentTimeMillis());
-            // Do the upsert
-            if (!sets.isEmpty())
-            {
-                update.put("$set",sets);
-            }            
-            
-            _dbSessions.update(key,update,false,false,WriteConcern.SAFE);
-            
-            session.didActivate();
-
-            return version;
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-
-        return null;
-    }
-
-    /*------------------------------------------------------------ */
-    @Override
-    protected synchronized NoSqlSession loadSession(String clusterId)
-    {
-        DBObject o = _dbSessions.findOne(new BasicDBObject(__ID,clusterId));
-        
-        __log.debug("MongoSessionManager:id={} loaded={}", clusterId, o);
-        if (o == null)
-            return null;
-        
-        Boolean valid = (Boolean)o.get(__VALID);
-        __log.debug("MongoSessionManager:id={} valid={}", clusterId, valid);
-        if (valid == null || !valid)
-            return null;
-        
-        try
-        {
-            Object version = o.get(getContextAttributeKey(__VERSION));
-            Long created = (Long)o.get(__CREATED);
-            Long accessed = (Long)o.get(__ACCESSED);
-          
-            NoSqlSession session = null;
-
-            // get the session for the context
-            DBObject attrs = (DBObject)getNestedValue(o,getContextKey());
-
-            __log.debug("MongoSessionManager:attrs {}", attrs);
-            if (attrs != null)
-            {
-                __log.debug("MongoSessionManager: session {} present for context {}", clusterId, getContextKey());
-                //only load a session if it exists for this context
-                session = new NoSqlSession(this,created,accessed,clusterId,version);
-                
-                for (String name : attrs.keySet())
-                {
-                    //skip special metadata attribute which is not one of the actual session attributes
-                    if ( __METADATA.equals(name) )
-                        continue;
-                    
-                    String attr = decodeName(name);
-                    Object value = decodeValue(attrs.get(name));
-
-                    session.doPutOrRemove(attr,value);
-                    session.bindValue(attr,value);
-                }
-                session.didActivate();
-            }
-            else
-                __log.debug("MongoSessionManager: session  {} not present for context {}",clusterId, getContextKey());        
-
-            return session;
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-        return null;
-    }
-
     
-    
-    /*------------------------------------------------------------ */
-    /** 
-     * Remove the per-context sub document for this session id.
-     * @see org.eclipse.jetty.nosql.NoSqlSessionManager#remove(org.eclipse.jetty.nosql.NoSqlSession)
-     */
-    @Override
-    protected boolean remove(NoSqlSession session)
+    public MongoSessionDataStore getSessionDataStore()
     {
-        __log.debug("MongoSessionManager:remove:session {} for context {}",session.getClusterId(), getContextKey());
+        return _sessionDataStore;
+    }
+  
 
-        /*
-         * Check if the session exists and if it does remove the context
-         * associated with this session
-         */
-        BasicDBObject key = new BasicDBObject(__ID,session.getClusterId());
-        
-        DBObject o = _dbSessions.findOne(key,_version_1);
-
-        if (o != null)
-        {
-            BasicDBObject remove = new BasicDBObject();
-            BasicDBObject unsets = new BasicDBObject();
-            unsets.put(getContextKey(),1);
-            remove.put("$unset",unsets);
-            _dbSessions.update(key,remove,false,false,WriteConcern.SAFE);
-
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-
-    
-    
-    /** 
-     * @see org.eclipse.jetty.nosql.NoSqlSessionManager#expire(java.lang.String)
-     */
-    @Override
-    protected void expire (String idInCluster)
-    {
-        __log.debug("MongoSessionManager:expire session {} ", idInCluster);
-
-        //Expire the session for this context
-        super.expire(idInCluster);
-        
-        //If the outer session document has not already been marked invalid, do so.
-        DBObject validKey = new BasicDBObject(__VALID, true);       
-        DBObject o = _dbSessions.findOne(new BasicDBObject(__ID,idInCluster), validKey);
-        
-        if (o != null && (Boolean)o.get(__VALID))
-        {
-            BasicDBObject update = new BasicDBObject();
-            BasicDBObject sets = new BasicDBObject();
-            sets.put(__VALID,false);
-            sets.put(__INVALIDATED, System.currentTimeMillis());
-            update.put("$set",sets);
-                        
-            BasicDBObject key = new BasicDBObject(__ID,idInCluster);
-            _dbSessions.update(key,update,false,false,WriteConcern.SAFE);
-        }       
-    }
-    
-    
-    /*------------------------------------------------------------ */
-    /** 
-     * Change the session id. Note that this will change the session id for all contexts for which the session id is in use.
-     * @see org.eclipse.jetty.nosql.NoSqlSessionManager#update(org.eclipse.jetty.nosql.NoSqlSession, java.lang.String, java.lang.String)
-     */
-    @Override
-    protected void update(NoSqlSession session, String newClusterId, String newNodeId) throws Exception
-    {
-        BasicDBObject key = new BasicDBObject(__ID, session.getClusterId());
-        BasicDBObject sets = new BasicDBObject();
-        BasicDBObject update = new BasicDBObject(__ID, newClusterId);
-        sets.put("$set", update);
-        _dbSessions.update(key, sets, false, false,WriteConcern.SAFE);
-    }
-
-    /*------------------------------------------------------------ */
-    protected String encodeName(String name)
-    {
-        return name.replace("%","%25").replace(".","%2E");
-    }
-
-    /*------------------------------------------------------------ */
-    protected String decodeName(String name)
-    {
-        return name.replace("%2E",".").replace("%25","%");
-    }
-
-    /*------------------------------------------------------------ */
-    protected Object encodeName(Object value) throws IOException
-    {
-        if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date)
-        {
-            return value;
-        }
-        else if (value.getClass().equals(HashMap.class))
-        {
-            BasicDBObject o = new BasicDBObject();
-            for (Map.Entry<?, ?> entry : ((Map<?, ?>)value).entrySet())
-            {
-                if (!(entry.getKey() instanceof String))
-                {
-                    o = null;
-                    break;
-                }
-                o.append(encodeName(entry.getKey().toString()),encodeName(entry.getValue()));
-            }
-
-            if (o != null)
-                return o;
-        }
-        
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(bout);
-        out.reset();
-        out.writeUnshared(value);
-        out.flush();
-        return bout.toByteArray();
-    }
-
-    /*------------------------------------------------------------ */
-    protected Object decodeValue(final Object valueToDecode) throws IOException, ClassNotFoundException
-    {
-        if (valueToDecode == null || valueToDecode instanceof Number || valueToDecode instanceof String || valueToDecode instanceof Boolean || valueToDecode instanceof Date)
-        {
-            return valueToDecode;
-        }
-        else if (valueToDecode instanceof byte[])
-        {
-            final byte[] decodeObject = (byte[])valueToDecode;
-            final ByteArrayInputStream bais = new ByteArrayInputStream(decodeObject);
-            final ClassLoadingObjectInputStream objectInputStream = new ClassLoadingObjectInputStream(bais);
-            return objectInputStream.readUnshared();
-        }
-        else if (valueToDecode instanceof DBObject)
-        {
-            Map<String, Object> map = new HashMap<String, Object>();
-            for (String name : ((DBObject)valueToDecode).keySet())
-            {
-                String attr = decodeName(name);
-                map.put(attr,decodeValue(((DBObject)valueToDecode).get(name)));
-            }
-            return map;
-        }
-        else
-        {
-            throw new IllegalStateException(valueToDecode.getClass().toString());
-        }
-    }
-
-   
-    /*------------------------------------------------------------ */
-    private String getContextKey()
-    {
-        return __CONTEXT + "." + _contextId;
-    }
-    
-    /*------------------------------------------------------------ */
-    /** Get a dot separated key for 
-     * @param key
-     * @return
-     */
-    private String getContextAttributeKey(String attr)
-    {
-        return getContextKey()+ "." + attr;
-    }
-    
-    /*------------------------------------------------------------ */
-    @ManagedOperation(value="purge invalid sessions in the session store based on normal criteria", impact="ACTION")
-    public void purge()
-    {   
-        ((MongoSessionIdManager)_sessionIdManager).purge();
-    }
-    
-    
-    /*------------------------------------------------------------ */
-    @ManagedOperation(value="full purge of invalid sessions in the session store", impact="ACTION")
-    public void purgeFully()
-    {   
-        ((MongoSessionIdManager)_sessionIdManager).purgeFully();
-    }
-    
-    /*------------------------------------------------------------ */
-    @ManagedOperation(value="scavenge sessions known to this manager", impact="ACTION")
-    public void scavenge()
-    {
-        ((MongoSessionIdManager)_sessionIdManager).scavenge();
-    }
-    
-    /*------------------------------------------------------------ */
-    @ManagedOperation(value="scanvenge all sessions", impact="ACTION")
-    public void scavengeFully()
-    {
-        ((MongoSessionIdManager)_sessionIdManager).scavengeFully();
-    }
-    
     /*------------------------------------------------------------ */
     /**
      * returns the total number of session objects in the session store
@@ -712,81 +150,5 @@
     {
         return _dbSessions.find().count();      
     }
-    
-    /*------------------------------------------------------------ */
-    /**
-     * MongoDB keys are . delimited for nesting so .'s are protected characters
-     * 
-     * @param virtualHosts
-     * @param contextPath
-     * @return
-     */
-    private String createContextId(String[] virtualHosts, String contextPath)
-    {
-        String contextId = virtualHosts[0] + contextPath;
-        
-        contextId.replace('/', '_');
-        contextId.replace('.','_');
-        contextId.replace('\\','_');
-        
-        return contextId;
-    }
-
-    /*------------------------------------------------------------ */
-    /**
-     * Dig through a given dbObject for the nested value
-     */
-    private Object getNestedValue(DBObject dbObject, String nestedKey)
-    {
-        String[] keyChain = nestedKey.split("\\.");
-
-        DBObject temp = dbObject;
-
-        for (int i = 0; i < keyChain.length - 1; ++i)
-        {
-            temp = (DBObject)temp.get(keyChain[i]);
-            
-            if ( temp == null )
-            {
-                return null;
-            }
-        }
-
-        return temp.get(keyChain[keyChain.length - 1]);
-    }
-
-    
-    /*------------------------------------------------------------ */
-     /**
-     * ClassLoadingObjectInputStream
-     *
-     *
-     */
-    protected class ClassLoadingObjectInputStream extends ObjectInputStream
-    {
-        public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException
-        {
-            super(in);
-        }
-
-        public ClassLoadingObjectInputStream () throws IOException
-        {
-            super();
-        }
-
-        @Override
-        public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException
-        {
-            try
-            {
-                return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
-            }
-            catch (ClassNotFoundException e)
-            {
-                return super.resolveClass(cl);
-            }
-        }
-    }
-
 
 }
diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/jmx/MongoSessionManagerMBean.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/jmx/MongoSessionManagerMBean.java
index 58a2b44..1bef5d4 100644
--- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/jmx/MongoSessionManagerMBean.java
+++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/jmx/MongoSessionManagerMBean.java
@@ -22,11 +22,11 @@
 import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
 import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.server.session.jmx.AbstractSessionManagerMBean;
+import org.eclipse.jetty.server.session.jmx.SessionManagerMBean;
 import org.eclipse.jetty.util.annotation.ManagedObject;
 
 @ManagedObject("Mongo Session Manager MBean")
-public class MongoSessionManagerMBean extends AbstractSessionManagerMBean
+public class MongoSessionManagerMBean extends SessionManagerMBean
 {
 
     public MongoSessionManagerMBean(Object managedObject)
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java
index 4d29b13..d7b2420 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java
@@ -99,7 +99,7 @@
 
         if (nodeName != null)
         {
-            AbstractSessionIdManager sessionIdManager = new HashSessionIdManager();
+            AbstractSessionIdManager sessionIdManager = new HashSessionIdManager(server);
             sessionIdManager.setWorkerName(nodeName);
             server.setSessionIdManager(sessionIdManager);
         }
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
index e85b680..63d41a0 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java
@@ -29,7 +29,7 @@
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Response;
 import org.eclipse.jetty.server.UserIdentity;
-import org.eclipse.jetty.server.session.AbstractSession;
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 
@@ -109,17 +109,17 @@
             {
                 //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users
                 //(indicated by SESSION_SECURED not being set on the session) then we should change id
-                if (httpSession.getAttribute(AbstractSession.SESSION_CREATED_SECURE)!=Boolean.TRUE)
+                if (httpSession.getAttribute(Session.SESSION_CREATED_SECURE)!=Boolean.TRUE)
                 {
-                    if (httpSession instanceof AbstractSession)
+                    if (httpSession instanceof Session)
                     {
-                        AbstractSession abstractSession = (AbstractSession)httpSession;
-                        String oldId = abstractSession.getId();
-                        abstractSession.renewId(request);
-                        abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
-                        if (abstractSession.isIdChanged() && response != null && (response instanceof Response))
-                            ((Response)response).addCookie(abstractSession.getSessionManager().getSessionCookie(abstractSession, request.getContextPath(), request.isSecure()));
-                        LOG.debug("renew {}->{}",oldId,abstractSession.getId());
+                        Session s = (Session)httpSession;
+                        String oldId = s.getId();
+                        s.renewId(request);
+                        s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
+                        if (s.isIdChanged() && response != null && (response instanceof Response))
+                            ((Response)response).addCookie(s.getSessionManager().getSessionCookie(s, request.getContextPath(), request.isSecure()));
+                        LOG.debug("renew {}->{}",oldId,s.getId());
                     }
                     else
                         LOG.warn("Unable to renew session "+httpSession);
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
index 3a7c006..6c9681a 100644
--- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
+++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java
@@ -33,7 +33,7 @@
 import org.eclipse.jetty.security.LoginService;
 import org.eclipse.jetty.security.SecurityHandler;
 import org.eclipse.jetty.server.UserIdentity;
-import org.eclipse.jetty.server.session.AbstractSession;
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 
@@ -89,7 +89,7 @@
         if (security!=null)
             security.logout(this);
         if (_session!=null)
-            _session.removeAttribute(AbstractSession.SESSION_CREATED_SECURE);
+            _session.removeAttribute(Session.SESSION_CREATED_SECURE);
     }
 
     @Override
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
index e358cd6..ca6fdf6 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java
@@ -76,7 +76,7 @@
 import org.eclipse.jetty.http.MimeTypes;
 import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.server.handler.ContextHandler.Context;
-import org.eclipse.jetty.server.session.AbstractSession;
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.util.Attributes;
 import org.eclipse.jetty.util.AttributesMap;
 import org.eclipse.jetty.util.IO;
@@ -1500,14 +1500,14 @@
         if (session == null)
             throw new IllegalStateException("No session");
 
-        if (session instanceof AbstractSession)
+        if (session instanceof Session)
         {
-            AbstractSession abstractSession =  ((AbstractSession)session);
-            abstractSession.renewId(this);
+            Session s =  ((Session)session);
+            s.renewId(this);
             if (getRemoteUser() != null)
-                abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
-            if (abstractSession.isIdChanged())
-                _channel.getResponse().addCookie(_sessionManager.getSessionCookie(abstractSession, getContextPath(), isSecure()));
+                s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
+            if (s.isIdChanged())
+                _channel.getResponse().addCookie(_sessionManager.getSessionCookie(s, getContextPath(), isSecure()));
         }
 
         return session.getId();
@@ -1711,7 +1711,7 @@
             return false;
 
         HttpSession session = getSession(false);
-        return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session)));
+        return (session != null && _sessionManager.getSessionIdManager().getId(_requestedSessionId).equals(_sessionManager.getId(session)));
     }
 
     /* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
index 9a5b170..2f5382b 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java
@@ -448,7 +448,7 @@
         if (!sessionManager.isValid(session))
             return url;
 
-        String id = sessionManager.getNodeId(session);
+        String id = sessionManager.getExtendedId(session);
 
         if (uri == null)
             uri = new HttpURI(url);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java
index a7f12fb..755b863 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java
@@ -19,8 +19,8 @@
 package org.eclipse.jetty.server;
 
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
 
+import org.eclipse.jetty.server.session.Session;
 import org.eclipse.jetty.util.component.LifeCycle;
 
 /** Session ID Manager.
@@ -29,28 +29,31 @@
 public interface SessionIdManager extends LifeCycle
 {
     /**
-     * @param id The session ID without any cluster node extension
+     * @param id The plain session ID (ie no workername extension)
      * @return True if the session ID is in use by at least one context.
      */
-    public boolean idInUse(String id);
+    public boolean isIdInUse(String id);
+    
     
     /**
-     * Add a session to the list of known sessions for a given ID.
-     * @param session The session
+     * Notify the sessionid manager that a particular session id is in use
+     * @param the session whose id is being used
      */
-    public void addSession(HttpSession session);
+    public void useId (Session session);
     
     /**
-     * Remove session from the list of known sessions for a given ID.
-     * @param session the session to remove
+     * Remove id
+     * @param id the plain session id (no workername extension) of the session to remove
+     * @return true if the id was removed, false otherwise
      */
-    public void removeSession(HttpSession session);
+    public boolean removeId (String id);
     
     /**
-     * Call {@link HttpSession#invalidate()} on all known sessions for the given id.
+     * Invalidate all sessions on all contexts that share the same id.
+     * 
      * @param id The session ID without any cluster node extension
      */
-    public void invalidateAll(String id);
+    public void expireAll(String id);
     
     /**
      * Create a new Session ID.
@@ -67,30 +70,36 @@
     
     
     /* ------------------------------------------------------------ */
-    /** Get a cluster ID from a node ID.
+    /** Get just the session id from an id that includes the worker name
+     * as a suffix.
+     * 
      * Strip node identifier from a located session ID.
-     * @param nodeId the node id
+     * @param qualifiedId the session id including the worker name
      * @return the cluster id
      */
-    public String getClusterId(String nodeId);
+    public String getId(String qualifiedId);
+    
+    
     
     /* ------------------------------------------------------------ */
-    /** Get a node ID from a cluster ID and a request
-     * @param clusterId The ID of the session
+    /** Get an extended id for a session. An extended id contains
+     * the workername as a suffix.
+     * 
+     * @param id The id of the session
      * @param request The request that for the session (or null)
-     * @return The session ID qualified with the node ID.
+     * @return The session id qualified with the worker name
      */
-    public String getNodeId(String clusterId,HttpServletRequest request);
+    public String getExtendedId(String id,HttpServletRequest request);
     
     
     /* ------------------------------------------------------------ */
     /** Change the existing session id.
     * 
-    * @param oldClusterId the old cluster id
-    * @param oldNodeId the old node id
+    * @param oldId the old plain session id
+    * @param oldExtendedId the old fully qualified id
     * @param request the request containing the session
     */
-    public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request);    
+    public void renewSessionId(String oldId, String oldExtendedId, HttpServletRequest request);    
 
     
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java
index a2fda2e..cfef6a4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java
@@ -194,13 +194,7 @@
      */
     public SessionIdManager getSessionIdManager();
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the cross context session id manager.
-     * @deprecated use {@link #getSessionIdManager()}
-     */
-    @Deprecated
-    public SessionIdManager getMetaManager();
+
 
     /* ------------------------------------------------------------ */
     /**
@@ -222,17 +216,17 @@
     /**
      * @param session the session object
      * @return the unique id of the session within the cluster, extended with an optional node id.
-     * @see #getClusterId(HttpSession)
+     * @see #getId(HttpSession)
      */
-    public String getNodeId(HttpSession session);
+    public String getExtendedId(HttpSession session);
 
     /* ------------------------------------------------------------ */
     /**
      * @param session the session object
      * @return the unique id of the session within the cluster (without a node id extension)
-     * @see #getNodeId(HttpSession)
+     * @see #getExtendedId(HttpSession)
      */
-    public String getClusterId(HttpSession session);
+    public String getId(HttpSession session);
 
     /* ------------------------------------------------------------ */
     /**
@@ -308,10 +302,10 @@
     /* ------------------------------------------------------------ */
     /** Change the existing session id.
     * 
-    * @param oldClusterId the old cluster id
-    * @param oldNodeId the old node id
-    * @param newClusterId the new cluster id
-    * @param newNodeId the new node id
+    * @param oldId the old session id
+    * @param oldExtendedId the session id including worker suffix
+    * @param newId the new session id
+    * @param newExtendedId the new session id including worker suffix
     */
-    public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId);  
+    public void renewSessionId(String oldId, String oldExtendedId, String newId, String newExtendedId);  
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java
deleted file mode 100644
index 06281e3..0000000
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSession.java
+++ /dev/null
@@ -1,664 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.server.session;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSessionActivationListener;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionBindingListener;
-import javax.servlet.http.HttpSessionContext;
-import javax.servlet.http.HttpSessionEvent;
-
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- *
- * <p>
- * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package.
- * </p>
- *
- */
-@SuppressWarnings("deprecation")
-public abstract class AbstractSession implements AbstractSessionManager.SessionIf
-{
-    final static Logger LOG = SessionHandler.LOG;
-    public final static String SESSION_CREATED_SECURE="org.eclipse.jetty.security.sessionCreatedSecure";
-    private  String _clusterId; // ID without any node (ie "worker") id appended
-    private  String _nodeId;    // ID of session with node(ie "worker") id appended
-    private final AbstractSessionManager _manager;
-    private boolean _idChanged;
-    private final long _created;
-    private long _cookieSet;
-    private long _accessed;         // the time of the last access
-    private long _lastAccessed;     // the time of the last access excluding this one
-    private boolean _invalid;
-    private boolean _doInvalidate;
-    private long _maxIdleMs;
-    private boolean _newSession;
-    private int _requests;
-
-
-
-    /* ------------------------------------------------------------- */
-    protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
-    {
-        _manager = abstractSessionManager;
-
-        _newSession=true;
-        _created=System.currentTimeMillis();
-        _clusterId=_manager._sessionIdManager.newSessionId(request,_created);
-        _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request);
-        _accessed=_created;
-        _lastAccessed=_created;
-        _requests=1;
-        _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
-        if (LOG.isDebugEnabled())
-            LOG.debug("new session & id "+_nodeId+" "+_clusterId);
-    }
-
-    /* ------------------------------------------------------------- */
-    protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
-    {
-        _manager = abstractSessionManager;
-        _created=created;
-        _clusterId=clusterId;
-        _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,null);
-        _accessed=accessed;
-        _lastAccessed=accessed;
-        _requests=1;
-        _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
-        if (LOG.isDebugEnabled())
-            LOG.debug("new session "+_nodeId+" "+_clusterId);
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * asserts that the session is valid
-     * @throws IllegalStateException if the sesion is invalid
-     */
-    protected void checkValid() throws IllegalStateException
-    {
-        if (_invalid)
-            throw new IllegalStateException();
-    }
-    
-    /* ------------------------------------------------------------- */
-    /** Check to see if session has expired as at the time given.
-     * @param time the time in milliseconds
-     * @return true if expired
-     */
-    protected boolean checkExpiry(long time)
-    {
-        if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
-            return true;
-        return false;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public AbstractSession getSession()
-    {
-        return this;
-    }
-
-    /* ------------------------------------------------------------- */
-    public long getAccessed()
-    {
-        synchronized (this)
-        {
-            return _accessed;
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    public abstract Map<String,Object> getAttributeMap();
-
-
- 
-    
-
-    /* ------------------------------------------------------------ */
-    public abstract int getAttributes();
-  
-
- 
-
-    /* ------------------------------------------------------------ */
-    public abstract Set<String> getNames();
-  
-
-    /* ------------------------------------------------------------- */
-    public long getCookieSetTime()
-    {
-        return _cookieSet;
-    }
-    
-    /* ------------------------------------------------------------- */
-    public void setCookieSetTime(long time)
-    {
-        _cookieSet = time;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public long getCreationTime() throws IllegalStateException
-    {
-        checkValid();
-        return _created;
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public String getId() throws IllegalStateException
-    {
-        return _manager._nodeIdInSessionId?_nodeId:_clusterId;
-    }
-
-    /* ------------------------------------------------------------- */
-    public String getNodeId()
-    {
-        return _nodeId;
-    }
-
-    /* ------------------------------------------------------------- */
-    public String getClusterId()
-    {
-        return _clusterId;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public long getLastAccessedTime() throws IllegalStateException
-    {
-        checkValid();
-        return _lastAccessed;
-    }
-    
-    /* ------------------------------------------------------------- */
-    public void setLastAccessedTime(long time)
-    {
-        _lastAccessed = time;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public int getMaxInactiveInterval()
-    {
-        return (int)(_maxIdleMs/1000);
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpSession#getServletContext()
-     */
-    @Override
-    public ServletContext getServletContext()
-    {
-        return _manager._context;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Deprecated
-    @Override
-    public HttpSessionContext getSessionContext() throws IllegalStateException
-    {
-        checkValid();
-        return AbstractSessionManager.__nullSessionContext;
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #getAttribute}
-     */
-    @Deprecated
-    @Override
-    public Object getValue(String name) throws IllegalStateException
-    {
-        return getAttribute(name);
-    }
-
- 
-
-    /* ------------------------------------------------------------ */
-    public void renewId(HttpServletRequest request)
-    {
-        _manager._sessionIdManager.renewSessionId(getClusterId(), getNodeId(), request); 
-        setIdChanged(true);
-    }
-       
-    /* ------------------------------------------------------------- */
-    public SessionManager getSessionManager()
-    {
-        return _manager;
-    }
-
-    /* ------------------------------------------------------------ */
-    protected void setClusterId (String clusterId)
-    {
-        _clusterId = clusterId;
-    }
-    
-    /* ------------------------------------------------------------ */
-    protected void setNodeId (String nodeId)
-    {
-        _nodeId = nodeId;
-    }
-    
-
-    /* ------------------------------------------------------------ */
-    protected boolean access(long time)
-    {
-        synchronized(this)
-        {
-            if (_invalid)
-                return false;
-            _newSession=false;
-            _lastAccessed=_accessed;
-            _accessed=time;
-
-            if (checkExpiry(time))
-            {
-                invalidate();
-                return false;
-            }
-            _requests++;
-            return true;
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    protected void complete()
-    {
-        synchronized(this)
-        {
-            _requests--;
-            if (_doInvalidate && _requests<=0  )
-                doInvalidate();
-        }
-    }
-
-
-    /* ------------------------------------------------------------- */
-    protected void timeout() throws IllegalStateException
-    {
-        // remove session from context and invalidate other sessions with same ID.
-        _manager.removeSession(this,true);
-
-        // Notify listeners and unbind values
-        boolean do_invalidate=false;
-        synchronized (this)
-        {
-            if (!_invalid)
-            {
-                if (_requests<=0)
-                    do_invalidate=true;
-                else
-                    _doInvalidate=true;
-            }
-        }
-        if (do_invalidate)
-            doInvalidate();
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public void invalidate() throws IllegalStateException
-    {
-        checkValid();
-        // remove session from context and invalidate other sessions with same ID.
-        _manager.removeSession(this,true);
-        doInvalidate();
-    }
-
-    /* ------------------------------------------------------------- */
-    protected void doInvalidate() throws IllegalStateException
-    {
-        try
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("invalidate {}",_clusterId);
-            if (isValid())
-                clearAttributes();
-        }
-        finally
-        {
-            synchronized (this)
-            {
-                // mark as invalid
-                _invalid=true;
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    public abstract void clearAttributes();
-   
-
-    /* ------------------------------------------------------------- */
-    public boolean isIdChanged()
-    {
-        return _idChanged;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public boolean isNew() throws IllegalStateException
-    {
-        checkValid();
-        return _newSession;
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #setAttribute}
-     */
-    @Deprecated
-    @Override
-    public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
-    {
-        changeAttribute(name,value);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void removeAttribute(String name)
-    {
-        setAttribute(name,null);
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #removeAttribute}
-     */
-    @Deprecated
-    @Override
-    public void removeValue(java.lang.String name) throws IllegalStateException
-    {
-        removeAttribute(name);
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    public Enumeration<String> getAttributeNames()
-    {
-        synchronized (this)
-        {
-            checkValid();
-            return doGetAttributeNames();
-        }
-    }
-    
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #getAttributeNames}
-     */
-    @Deprecated
-    @Override
-    public String[] getValueNames() throws IllegalStateException
-    {
-        synchronized(this)
-        {
-            checkValid();
-            Enumeration<String> anames = doGetAttributeNames();
-            if (anames == null)
-                return new String[0];
-            ArrayList<String> names = new ArrayList<String>();
-            while (anames.hasMoreElements())
-                names.add(anames.nextElement());
-            return names.toArray(new String[names.size()]);
-        }
-    }
-    
-
-    /* ------------------------------------------------------------ */
-    public abstract Object doPutOrRemove(String name, Object value);
- 
-
-    /* ------------------------------------------------------------ */
-    public abstract Object doGet(String name);
-    
-    
-    /* ------------------------------------------------------------ */
-    public abstract Enumeration<String> doGetAttributeNames();
-    
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    public Object getAttribute(String name)
-    {
-        synchronized (this)
-        {
-            checkValid();
-            return doGet(name);
-        }
-    }
-   
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void setAttribute(String name, Object value)
-    {
-        changeAttribute(name,value);
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @param name the name of the attribute
-     * @param value the value of the attribute
-     * @return true if attribute changed
-     * @deprecated use changeAttribute(String,Object) instead
-     */
-    @Deprecated
-    protected boolean updateAttribute (String name, Object value)
-    {
-        Object old=null;
-        synchronized (this)
-        {
-            checkValid();
-            old=doPutOrRemove(name,value);
-        }
-
-        if (value==null || !value.equals(old))
-        {
-            if (old!=null)
-                unbindValue(name,old);
-            if (value!=null)
-                bindValue(name,value);
-
-            _manager.doSessionAttributeListeners(this,name,old,value);
-            return true;
-        }
-        return false;
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Either set (perhaps replace) or remove the value of the attribute
-     * in the session. The appropriate session attribute listeners are
-     * also called.
-     * 
-     * @param name the name of the attribute
-     * @param value the value of the attribute
-     * @return the old value for the attribute
-     */
-    protected Object changeAttribute (String name, Object value)
-    {
-        Object old=null;
-        synchronized (this)
-        {
-            checkValid();
-            old=doPutOrRemove(name,value);
-        }
-
-        callSessionAttributeListeners(name, value, old);
-
-        return old;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Call binding and attribute listeners based on the new and old
-     * values of the attribute.
-     * 
-     * @param name name of the attribute
-     * @param newValue  new value of the attribute
-     * @param oldValue previous value of the attribute
-     */
-    protected void callSessionAttributeListeners (String name, Object newValue, Object oldValue)
-    {
-        if (newValue==null || !newValue.equals(oldValue))
-        {
-            if (oldValue!=null)
-                unbindValue(name,oldValue);
-            if (newValue!=null)
-                bindValue(name,newValue);
-
-            _manager.doSessionAttributeListeners(this,name,oldValue,newValue);
-        }
-    }
-  
-
-    /* ------------------------------------------------------------- */
-    public void setIdChanged(boolean changed)
-    {
-        _idChanged=changed;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public void setMaxInactiveInterval(int secs)
-    {
-        _maxIdleMs=(long)secs*1000L;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public String toString()
-    {
-        return this.getClass().getName()+":"+getId()+"@"+hashCode();
-    }
-
-    /* ------------------------------------------------------------- */
-    /** 
-     * Bind value if value implements {@link HttpSessionBindingListener} (calls {@link HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)}) 
-     * @param name the name with which the object is bound or unbound  
-     * @param value the bound value
-     */
-    public void bindValue(java.lang.String name, Object value)
-    {
-        if (value!=null&&value instanceof HttpSessionBindingListener)
-            ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
-    }
-
-    /* ------------------------------------------------------------ */
-    public boolean isValid()
-    {
-        return !_invalid;
-    }
-
-    /* ------------------------------------------------------------- */
-    protected void cookieSet()
-    {
-        synchronized (this)
-        {
-            _cookieSet=_accessed;
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    public int getRequests()
-    {
-        synchronized (this)
-        {
-            return _requests;
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    public void setRequests(int requests)
-    {
-        synchronized (this)
-        {
-            _requests=requests;
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * Unbind value if value implements {@link HttpSessionBindingListener} (calls {@link HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent)}) 
-     * @param name the name with which the object is bound or unbound  
-     * @param value the bound value
-     */
-    public void unbindValue(java.lang.String name, Object value)
-    {
-        if (value!=null&&value instanceof HttpSessionBindingListener)
-            ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
-    }
-
-    /* ------------------------------------------------------------- */
-    public void willPassivate()
-    {
-        synchronized(this)
-        {
-            HttpSessionEvent event = new HttpSessionEvent(this);
-            for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
-            {
-                Object value = iter.next();
-                if (value instanceof HttpSessionActivationListener)
-                {
-                    HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
-                    listener.sessionWillPassivate(event);
-                }
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    public void didActivate()
-    {
-        synchronized(this)
-        {
-            HttpSessionEvent event = new HttpSessionEvent(this);
-            for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
-            {
-                Object value = iter.next();
-                if (value instanceof HttpSessionActivationListener)
-                {
-                    HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
-                    listener.sessionDidActivate(event);
-                }
-            }
-        }
-    }
-
-
-}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java
new file mode 100644
index 0000000..3ea77d9
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java
@@ -0,0 +1,101 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+
+/**
+ * AbstractSessionDataStore
+ *
+ *
+ */
+public abstract class AbstractSessionDataStore extends AbstractLifeCycle implements SessionDataStore
+{
+    protected SessionContext _context; //context associated with this session data store
+
+
+    public abstract void doStore(String id, SessionData data, boolean isNew) throws Exception;
+
+   
+
+    
+    public void initialize (SessionContext context)
+    {
+        if (isStarted())
+            throw new IllegalStateException("Context set after SessionDataStore started");
+        _context = context;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
+     */
+    @Override
+    public void store(String id, SessionData data) throws Exception
+    {
+        long lastSave = data.getLastSaved();
+        
+        data.setLastSaved(System.currentTimeMillis());
+        try
+        {
+            doStore(id, data, (lastSave<=0));
+        }
+        catch (Exception e)
+        {
+            //reset last save time
+            data.setLastSaved(lastSave);
+        }
+        finally
+        {
+            data.setDirty(false);
+        }
+    }
+    
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
+     */
+    @Override
+    public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
+    {
+        return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
+    }
+ 
+    protected void checkStarted () throws IllegalStateException
+    {
+        if (isStarted())
+            throw new IllegalStateException("Already started");
+    }
+
+
+
+
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_context == null)
+            throw new IllegalStateException ("No SessionContext");
+        
+        super.doStart();
+    }
+    
+    
+    
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
index 32cff50..aa5e723 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
@@ -19,19 +19,24 @@
 package org.eclipse.jetty.server.session;
 
 import java.security.SecureRandom;
+import java.util.HashSet;
 import java.util.Random;
+import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.SessionIdManager;
+import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.util.component.AbstractLifeCycle;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 
 public abstract class AbstractSessionIdManager extends AbstractLifeCycle implements SessionIdManager
 {
-    private static final Logger LOG = Log.getLogger(AbstractSessionIdManager.class);
-
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
     private final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId";
 
     protected Random _random;
@@ -39,18 +44,41 @@
     protected String _workerName;
     protected String _workerAttr;
     protected long _reseed=100000L;
+    protected Server _server;
+    protected SessionScavenger _scavenger;
 
     /* ------------------------------------------------------------ */
-    public AbstractSessionIdManager()
+    public AbstractSessionIdManager(Server server)
     {
+        _server = server;
     }
 
     /* ------------------------------------------------------------ */
-    public AbstractSessionIdManager(Random random)
+    public AbstractSessionIdManager(Server server, Random random)
     {
+        this(server);
         _random=random;
     }
 
+    
+    public void setServer (Server server)
+    {
+        _server = server;
+    }
+    
+    public Server getServer ()
+    {
+        return _server;
+    }
+
+    
+    public void setSessionScavenger (SessionScavenger scavenger)
+    {
+        _scavenger = scavenger;
+        _scavenger.setSessionIdManager(this);
+    }
+   
+    
 
     /* ------------------------------------------------------------ */
     /**
@@ -65,6 +93,8 @@
         return _workerName;
     }
 
+    
+    
     /* ------------------------------------------------------------ */
     /**
      * Set the workername. If set, the workername is dot appended to the session
@@ -133,14 +163,14 @@
             String requested_id=request.getRequestedSessionId();
             if (requested_id!=null)
             {
-                String cluster_id=getClusterId(requested_id);
-                if (idInUse(cluster_id))
+                String cluster_id=getId(requested_id);
+                if (isIdInUse(cluster_id))
                     return cluster_id;
             }
 
             // Else reuse any new session ID already defined for this request.
             String new_id=(String)request.getAttribute(__NEW_SESSION_ID);
-            if (new_id!=null&&idInUse(new_id))
+            if (new_id!=null&&isIdInUse(new_id))
                 return new_id;
 
             // pick a new unique ID!
@@ -156,7 +186,7 @@
     {
         // pick a new unique ID!
         String id=null;
-        while (id==null||id.length()==0||idInUse(id))
+        while (id==null||id.length()==0||isIdInUse(id))
         {
             long r0=_weakRandom
                     ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32))
@@ -198,23 +228,32 @@
     }
 
 
-    /* ------------------------------------------------------------ */
-    @Override
-    public abstract void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request);
 
     
     /* ------------------------------------------------------------ */
     @Override
     protected void doStart() throws Exception
     {
+        if (_server == null)
+            throw new IllegalStateException("No Server for SessionIdManager");
        initRandom();
        _workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
+       
+       if (_scavenger == null)
+       {
+           LOG.warn("No SessionScavenger set, using defaults");
+           _scavenger = new SessionScavenger();
+           _scavenger.setSessionIdManager(this);
+       }
+       
+       _scavenger.start();
     }
 
     /* ------------------------------------------------------------ */
     @Override
     protected void doStop() throws Exception
     {
+        _scavenger.stop();
     }
 
     /* ------------------------------------------------------------ */
@@ -249,7 +288,7 @@
      * @return sessionId plus any worker ID.
      */
     @Override
-    public String getNodeId(String clusterId, HttpServletRequest request)
+    public String getExtendedId(String clusterId, HttpServletRequest request)
     {
         if (_workerName!=null)
         {
@@ -266,15 +305,85 @@
 
     /** Get the session ID without any worker ID.
      *
-     * @param nodeId the node id
+     * @param extendedId the session id with the worker extension
      * @return sessionId without any worker ID.
      */
     @Override
-    public String getClusterId(String nodeId)
+    public String getId(String extendedId)
     {
-        int dot=nodeId.lastIndexOf('.');
-        return (dot>0)?nodeId.substring(0,dot):nodeId;
+        int dot=extendedId.lastIndexOf('.');
+        return (dot>0)?extendedId.substring(0,dot):extendedId;
     }
 
+    /** 
+     * Remove an id from use by telling all contexts to remove a session with this id.
+     * 
+     * @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
+     */
+    @Override
+    public void expireAll(String id)
+    {
+        //take the id out of the list of known sessionids for this node
+        if (removeId(id))
+        {
+            //tell all contexts that may have a session object with this id to
+            //get rid of them
+            for (SessionManager manager:getSessionManagers())
+            {
+                manager.invalidate(id);
+            }
+        }
+    }
 
+    public void invalidateAll (String id)
+    {
+        //take the id out of the list of known sessionids for this node
+        if (removeId(id))
+        {
+            //tell all contexts that may have a session object with this id to
+            //get rid of them
+            for (SessionManager manager:getSessionManagers())
+            {         
+                manager.invalidate(id);
+            } 
+        }
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
+     */
+    @Override
+    public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
+    { 
+        //generate a new id
+        String newClusterId = newSessionId(request.hashCode());
+        
+        removeId(oldClusterId);//remove the old one from the list
+
+        //tell all contexts to update the id 
+        for (SessionManager manager:getSessionManagers())
+        {
+            manager.renewSessionId(oldClusterId, oldNodeId, newClusterId, getExtendedId(newClusterId, request));
+        }
+    }
+    
+    
+    private Set<SessionManager> getSessionManagers()
+    {
+        Set<SessionManager> managers = new HashSet<>();
+
+        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
+        for (int i=0; contexts!=null && i<contexts.length; i++)
+        {
+            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+            if (sessionHandler != null) 
+            {
+                SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
+
+                if (manager != null)
+                    managers.add(manager);
+            }
+        }
+        return managers;
+    }
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java
new file mode 100644
index 0000000..cffb7e7
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java
@@ -0,0 +1,328 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Locker.Lock;
+
+/**
+ * AbstractSessionStore
+ *
+ * Basic behaviour for maintaining an in-memory store of Session objects and 
+ * making sure that any backing SessionDataStore is kept in sync.
+ */
+public abstract class AbstractSessionStore extends AbstractLifeCycle implements SessionStore
+{
+    final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    protected SessionDataStore _sessionDataStore;
+    protected StalenessStrategy _staleStrategy;
+    protected SessionManager _manager;
+    protected SessionContext _context;
+
+
+    
+
+    /**
+     * Create a new Session object from session data
+     * @param data
+     * @return
+     */
+    public abstract Session newSession (SessionData data);
+
+    
+    
+    /**
+     * Get the session matching the key
+     * @param id session id
+     * @return
+     */
+    public abstract Session doGet(String id);
+    
+    
+    
+    /**
+     * Put the session into the map if it wasn't already there
+     * 
+     * @param id the identity of the session
+     * @param session the session object
+     * @return null if the session wasn't already in the map, or the existing entry otherwise
+     */
+    public abstract Session doPutIfAbsent (String id, Session session);
+    
+    
+    
+    /**
+     * Check to see if the session exists in the store
+     * @param id
+     * @return
+     */
+    public abstract boolean doExists (String id);
+    
+    
+    
+    /**
+     * Remove the session with this identity from the store
+     * @param id
+     * @return true if removed false otherwise
+     */
+    public abstract Session doDelete (String id);
+    
+    
+    
+    
+    /**
+     * Get a list of keys for sessions that the store thinks has expired
+     * @return
+     */
+    public abstract Set<String> doGetExpiredCandidates();
+    
+    
+    
+    
+    /**
+     * 
+     */
+    public AbstractSessionStore ()
+    {
+    }
+    
+    
+    public void setSessionManager (SessionManager manager)
+    {
+        _manager = manager;
+    }
+    
+    public SessionManager getSessionManager()
+    {
+        return _manager;
+    }
+    
+    
+
+    public void initialize (SessionContext context)
+    {
+        if (isStarted())
+            throw new IllegalStateException("Context set after session store started");
+        _context = context;
+    }
+    
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_sessionDataStore == null)
+            throw new IllegalStateException ("No session data store configured");
+        
+        if (_manager == null)
+            throw new IllegalStateException ("No session manager");
+        
+        if (_context == null)
+            throw new IllegalStateException ("No ContextId");
+        
+        _sessionDataStore.initialize(_context);
+        _sessionDataStore.start();
+        
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        _sessionDataStore.stop();
+        super.doStop();
+    }
+
+    public SessionDataStore getSessionDataStore()
+    {
+        return _sessionDataStore;
+    }
+
+    public void setSessionDataStore(SessionDataStore sessionDataStore)
+    {
+        _sessionDataStore = sessionDataStore;
+    }
+    
+    public StalenessStrategy getStaleStrategy()
+    {
+        return _staleStrategy;
+    }
+
+    public void setStaleStrategy(StalenessStrategy staleStrategy)
+    {
+        _staleStrategy = staleStrategy;
+    }
+
+    /** 
+     * Get a session object.
+     * 
+     * If the session object is not in this session store, try getting
+     * the data for it from a SessionDataStore associated with the 
+     * session manager.
+     * 
+     * @see org.eclipse.jetty.server.session.SessionStore#get(java.lang.String)
+     */
+    @Override
+    public Session get(String id, boolean staleCheck) throws Exception
+    {
+        //look locally
+        Session session = doGet(id);
+        
+        
+        if (staleCheck && isStale(session))
+        {
+            //delete from session store so should reload from session data store
+            doDelete(id);
+            session = null;
+        }
+        
+        //not in session store, load the data for the session if possible
+        if (session == null && _sessionDataStore != null)
+        {
+            SessionData data = _sessionDataStore.load(id);
+            if (data != null)
+            {
+                session = newSession(data);
+                session.setSessionManager(_manager);
+                Session existing = doPutIfAbsent(id, session);
+                if (existing != null)
+                {
+                    //some other thread has got in first and added the session
+                    //so use it
+                    session = existing;
+                }
+            }
+        }
+        return session;
+    }
+
+    /** 
+     * Put the Session object into the session store. 
+     * If the session manager supports a session data store, write the
+     * session data through to the session data store.
+     * 
+     * @see org.eclipse.jetty.server.session.SessionStore#put(java.lang.String, org.eclipse.jetty.server.session.Session)
+     */
+    @Override
+    public void put(String id, Session session) throws Exception
+    {
+        if (id == null || session == null)
+            throw new IllegalArgumentException ("Put key="+id+" session="+(session==null?"null":session.getId()));
+        
+        session.setSessionManager(_manager);
+
+        //if the session is new, the data has changed, or the cache is considered stale, write it to any backing store
+        try (Lock lock = session.lock())
+        {
+            if ((session.isNew() || session.getSessionData().isDirty() || isStale(session)) && _sessionDataStore != null)
+            {
+                if (_sessionDataStore.isPassivating())
+                {
+                    session.willPassivate();
+                    try
+                    {
+                        _sessionDataStore.store(id, session.getSessionData());
+                    }
+                    finally
+                    {
+                        session.didActivate();
+                    }
+                }
+                else
+                    _sessionDataStore.store(id, session.getSessionData());
+            }
+
+        }
+
+        doPutIfAbsent(id,session);
+    }
+
+    /** 
+     * Check to see if the session object exists in this store.
+     * 
+     * @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
+     */
+    @Override
+    public boolean exists(String id)
+    {
+        return doExists(id);
+    }
+
+
+    /** 
+     * Remove a session object from this store and from any backing store.
+     * 
+     * @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
+     */
+    @Override
+    public Session delete(String id) throws Exception
+    {
+        if (_sessionDataStore != null)
+        {
+            boolean dsdel = _sessionDataStore.delete(id);
+            if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in db {}",id, dsdel);                   
+        }
+        return doDelete(id);
+    }
+
+    
+    
+    /**
+     * @param session
+     * @return
+     */
+    public boolean isStale (Session session)
+    {
+        if (_staleStrategy != null)
+            return _staleStrategy.isStale(session);
+        return false;
+    }
+    
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionStore#getExpired()
+     */
+    @Override
+    public Set<String> getExpired()
+    {
+       if (!isStarted())
+           return Collections.emptySet();
+       Set<String> candidates = doGetExpiredCandidates();
+       return _sessionDataStore.getExpired(candidates);
+    }
+
+
+
+
+
+    @Override
+    public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
+    {
+        return null;
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AlwaysStaleStrategy.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AlwaysStaleStrategy.java
new file mode 100644
index 0000000..264ea64
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AlwaysStaleStrategy.java
@@ -0,0 +1,39 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * AlwaysStale
+ *
+ *
+ */
+public class AlwaysStaleStrategy implements StalenessStrategy
+{
+
+    /** 
+     * @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
+     */
+    @Override
+    public boolean isStale(Session session)
+    {
+       return true;
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java
new file mode 100644
index 0000000..400834a
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java
@@ -0,0 +1,170 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.Set;
+
+/**
+ * CachingSessionDataStore
+ *
+ * A SessionDataStore is a mechanism for (persistently) storing data associated with sessions.
+ * This implementation delegates to a pluggable SessionDataStore for actually storing the 
+ * session data. It also uses a pluggable JCache implementation in front of the 
+ * delegate SessionDataStore to improve performance: accessing most persistent store
+ * technology can be expensive time-wise, so introducing a fronting cache 
+ * can increase performance. The cache implementation can either be a local cache, 
+ * a remote cache, or a clustered cache.
+ */
+public class CachingSessionDataStore extends AbstractSessionDataStore
+{
+
+    public interface SessionDataCache
+    {
+        public SessionData get (String id); //get mapped value
+        public boolean putIfAbsent (String id, SessionData data); //only insert if no mapping for key already
+        public boolean remove (String id); //remove the mapping for key, returns false if no mapping
+        public void put (String id, SessionData data); //overwrite or add the mapping
+        public void initialize(SessionContext context);
+    }
+    
+    
+    protected SessionDataStore _delegateDataStore;
+    protected SessionDataCache _cache;
+    
+    
+    public void setSessionDataStore (SessionDataStore store)
+    {
+        checkStarted();
+        _delegateDataStore = store;
+    }
+    
+    public SessionDataStore getSessionDataStore()
+    {
+        return _delegateDataStore;
+    }
+    
+    
+    public void setSessionDataCache (SessionDataCache cache)
+    {
+        checkStarted();
+        _cache = cache;
+    }
+    
+    public SessionDataCache getSessionDataCache ()
+    {
+        return _cache;
+    }
+    
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {
+        //check to see if the session data is already in our cache
+        SessionData d = _cache.get(id);
+        if (d == null)
+        {
+            //not in the cache, go get it from the store
+           d =  _delegateDataStore.load(id);
+           
+           //put it into the cache, unless another thread/node has put it into the cache
+          boolean inserted = _cache.putIfAbsent(id, d);
+          if (!inserted)
+          {
+              //some other thread/node put this data into the cache, so get it from there
+              SessionData d2 = _cache.get(id);
+              
+              if (d2 != null)
+                  d = d2;
+             //else: The cache either timed out the entry, or maybe the session data was being removed, and we're about to resurrect it!
+          }
+        }
+        return d;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {
+        //delete from the store and from the cache
+        _delegateDataStore.delete(id);
+        _cache.remove(id);
+        //TODO need to check removal at each level?
+        return false;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData, boolean)
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        //write to the SessionDataStore first
+        if (_delegateDataStore instanceof AbstractSessionDataStore)
+            ((AbstractSessionDataStore)_delegateDataStore).doStore(id, data, isNew);
+
+        //else??????
+        
+        //then update the cache with written data
+        _cache.put(id,data);
+
+    }
+
+    @Override
+    protected void doStart() throws Exception
+    {
+        _cache.initialize(_context);
+        _delegateDataStore.initialize(_context);
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        // TODO Auto-generated method stub
+        super.doStop();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+     */
+    @Override
+    public boolean isPassivating()
+    {
+       return true;
+    }
+
+    
+    
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java
new file mode 100644
index 0000000..4c2cb7c
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DatabaseAdaptor.java
@@ -0,0 +1,270 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Locale;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * DatabaseAdaptor
+ *
+ * Handles differences between databases.
+ *
+ * Postgres uses the getBytes and setBinaryStream methods to access
+ * a "bytea" datatype, which can be up to 1Gb of binary data. MySQL
+ * is happy to use the "blob" type and getBlob() methods instead.
+ *
+ */
+public class DatabaseAdaptor
+{
+    final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    String _dbName;
+    boolean _isLower;
+    boolean _isUpper;
+    
+    protected String _blobType; //if not set, is deduced from the type of the database at runtime
+    protected String _longType; //if not set, is deduced from the type of the database at runtime
+    private String _driverClassName;
+    private String _connectionUrl;
+    private Driver _driver;
+    private DataSource _datasource;
+    private String _jndiName;
+
+
+    public DatabaseAdaptor ()
+    {           
+    }
+    
+    
+    public void adaptTo(DatabaseMetaData dbMeta)  
+    throws SQLException
+    {
+        _dbName = dbMeta.getDatabaseProductName().toLowerCase(Locale.ENGLISH);
+        if (LOG.isDebugEnabled())
+            LOG.debug ("Using database {}",_dbName);
+        _isLower = dbMeta.storesLowerCaseIdentifiers();
+        _isUpper = dbMeta.storesUpperCaseIdentifiers(); 
+    }
+    
+
+    public void setBlobType(String blobType)
+    {
+        _blobType = blobType;
+    }
+    
+    public String getBlobType ()
+    {
+        if (_blobType != null)
+            return _blobType;
+
+        if (_dbName.startsWith("postgres"))
+            return "bytea";
+
+        return "blob";
+    }
+    
+
+    public void setLongType(String longType)
+    {
+        _longType = longType;
+    }
+    
+
+    public String getLongType ()
+    {
+        if (_longType != null)
+            return _longType;
+
+        if (_dbName == null)
+            throw new IllegalStateException ("DbAdaptor missing metadata");
+        
+        if (_dbName.startsWith("oracle"))
+            return "number(20)";
+
+        return "bigint";
+    }
+    
+
+    /**
+     * Convert a camel case identifier into either upper or lower
+     * depending on the way the db stores identifiers.
+     *
+     * @param identifier the raw identifier
+     * @return the converted identifier
+     */
+    public String convertIdentifier (String identifier)
+    {
+        if (_dbName == null)
+            throw new IllegalStateException ("DbAdaptor missing metadata");
+        
+        if (_isLower)
+            return identifier.toLowerCase(Locale.ENGLISH);
+        if (_isUpper)
+            return identifier.toUpperCase(Locale.ENGLISH);
+
+        return identifier;
+    }
+
+    
+    public String getDBName ()
+    {
+        return _dbName;
+    }
+
+
+    public InputStream getBlobInputStream (ResultSet result, String columnName)
+    throws SQLException
+    {
+        if (_dbName == null)
+            throw new IllegalStateException ("DbAdaptor missing metadata");
+        
+        if (_dbName.startsWith("postgres"))
+        {
+            byte[] bytes = result.getBytes(columnName);
+            return new ByteArrayInputStream(bytes);
+        }
+
+        Blob blob = result.getBlob(columnName);
+        return blob.getBinaryStream();
+    }
+
+
+    public boolean isEmptyStringNull ()
+    {
+        if (_dbName == null)
+            throw new IllegalStateException ("DbAdaptor missing metadata");
+        
+        return (_dbName.startsWith("oracle"));
+    }
+    
+    /**
+     * rowId is a reserved word for Oracle, so change the name of this column
+     * @return true if db in use is oracle
+     */
+    public boolean isRowIdReserved ()
+    {
+        if (_dbName == null)
+            throw new IllegalStateException ("DbAdaptor missing metadata");
+        
+        return (_dbName != null && _dbName.startsWith("oracle"));
+    }
+
+    /**
+     * Configure jdbc connection information via a jdbc Driver
+     *
+     * @param driverClassName the driver classname
+     * @param connectionUrl the driver connection url
+     */
+    public void setDriverInfo (String driverClassName, String connectionUrl)
+    {
+        _driverClassName=driverClassName;
+        _connectionUrl=connectionUrl;
+    }
+
+    /**
+     * Configure jdbc connection information via a jdbc Driver
+     *
+     * @param driverClass the driver class
+     * @param connectionUrl the driver connection url
+     */
+    public void setDriverInfo (Driver driverClass, String connectionUrl)
+    {
+        _driver=driverClass;
+        _connectionUrl=connectionUrl;
+    }
+
+
+    public void setDatasource (DataSource ds)
+    {
+        _datasource = ds;
+    }
+    
+    public void setDatasourceName (String jndi)
+    {
+        _jndiName=jndi;
+    }
+
+    public void initialize ()
+    throws Exception
+    {
+        if (_datasource != null)
+            return; //already set up
+        
+        if (_jndiName!=null)
+        {
+            InitialContext ic = new InitialContext();
+            _datasource = (DataSource)ic.lookup(_jndiName);
+        }
+        else if ( _driver != null && _connectionUrl != null )
+        {
+            DriverManager.registerDriver(_driver);
+        }
+        else if (_driverClassName != null && _connectionUrl != null)
+        {
+            Class.forName(_driverClassName);
+        }
+        else
+        {
+            try
+            {
+                InitialContext ic = new InitialContext();
+                _datasource = (DataSource)ic.lookup("jdbc/sessions"); //last ditch effort
+            }
+            catch (NamingException e)
+            {
+                throw new IllegalStateException("No database configured for sessions");
+            }
+        }
+    }
+    
+   
+    
+    /**
+     * Get a connection from the driver or datasource.
+     *
+     * @return the connection for the datasource
+     * @throws SQLException if unable to get the connection
+     */
+    protected Connection getConnection ()
+    throws SQLException
+    {
+        if (_datasource != null)
+            return _datasource.getConnection();
+        else
+            return DriverManager.getConnection(_connectionUrl);
+    }
+    
+}
\ No newline at end of file
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java
new file mode 100644
index 0000000..30fb64d
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java
@@ -0,0 +1,312 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * FileSessionDataStore
+ *
+ * A file-based store of session data.
+ */
+public class FileSessionDataStore extends AbstractSessionDataStore
+{
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    private File _storeDir;
+    private boolean _deleteUnrestorableFiles = false;
+    
+
+
+    @Override
+    protected void doStart() throws Exception
+    {
+        initializeStore();
+        super.doStart();
+    }
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        super.doStop();
+    }
+
+    public File getStoreDir()
+    {
+        return _storeDir;
+    }
+
+    public void setStoreDir(File storeDir)
+    {
+        checkStarted();
+        _storeDir = storeDir;
+    }
+
+    public boolean isDeleteUnrestorableFiles()
+    {
+        return _deleteUnrestorableFiles;
+    }
+
+    public void setDeleteUnrestorableFiles(boolean deleteUnrestorableFiles)
+    {
+        checkStarted();
+        _deleteUnrestorableFiles = deleteUnrestorableFiles;
+    }
+
+ 
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {   
+        File file = null;
+        if (_storeDir != null)
+        {
+            file = new File(_storeDir, getFileName(id));
+            if (file.exists() && file.getParentFile().equals(_storeDir))
+            {
+                file.delete();
+                return true;
+            }
+        }
+         
+        return false;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired()
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+        //we don't want to open up each file and check, so just leave it up to the SessionStore
+        return candidates;
+    }
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {  
+        final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        Runnable r = new Runnable()
+        {
+            public void run ()
+            {
+                File file = new File(_storeDir,getFileName(id));
+
+                if (!file.exists())
+                {
+                    if (LOG.isDebugEnabled())
+                        LOG.debug("No file: {}",file);
+                    return;
+                }
+
+                try (FileInputStream in = new FileInputStream(file))
+                {
+                    SessionData data = load(in);
+                    //delete restored file
+                    file.delete();
+                    reference.set(data);
+                }
+                catch (UnreadableSessionDataException e)
+                {
+                    if (isDeleteUnrestorableFiles() && file.exists() && file.getParentFile().equals(_storeDir));
+                    {
+                        file.delete();
+                        LOG.warn("Deleted unrestorable file for session {}", id);
+                    }
+                    exception.set(e);
+                }
+                catch (Exception e)
+                {
+                    exception.set(e);
+                }
+            }
+        };
+        //ensure this runs with the context classloader set
+        _context.run(r);
+        
+        if (exception.get() != null)
+            throw exception.get();
+        
+        return reference.get();
+    }
+    
+        
+
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData)
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        File file = null;
+        if (_storeDir != null)
+        {
+            file = new File(_storeDir, getFileName(id));
+            if (file.exists())
+                file.delete();
+
+            try(FileOutputStream fos = new FileOutputStream(file,false))
+            {
+                save(fos, id, data);
+            }
+            catch (Exception e)
+            { 
+                if (file != null) 
+                    file.delete(); // No point keeping the file if we didn't save the whole session
+                throw new UnwriteableSessionDataException(id, _context,e);             
+            }
+        }
+    }
+    
+    public void initializeStore ()
+    {
+        if (_storeDir == null)
+            throw new IllegalStateException("No file store specified");
+
+        if (!_storeDir.exists())
+            _storeDir.mkdirs();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+     */
+    @Override
+    public boolean isPassivating()
+    {
+        return true;
+    }
+    
+    /* ------------------------------------------------------------ */
+    private void save(OutputStream os, String id, SessionData data)  throws IOException
+    {    
+        DataOutputStream out = new DataOutputStream(os);
+        out.writeUTF(id);
+        out.writeUTF(_context.getCanonicalContextPath());
+        out.writeUTF(_context.getVhost());
+        out.writeUTF(data.getLastNode());
+        out.writeLong(data.getCreated());
+        out.writeLong(data.getAccessed());
+        out.writeLong(data.getLastAccessed());
+        out.writeLong(data.getCookieSet());
+        out.writeLong(data.getExpiry());
+        out.writeLong(data.getMaxInactiveMs());
+        
+        List<String> keys = new ArrayList<String>(data.getKeys());
+        out.writeInt(keys.size());
+        ObjectOutputStream oos = new ObjectOutputStream(out);
+        for (String name:keys)
+        {
+            oos.writeUTF(name);
+            oos.writeObject(data.getAttribute(name));
+        }
+    }
+
+    private String getFileName (String id)
+    {
+        return _context.getCanonicalContextPath()+"_"+_context.getVhost()+"_"+id;
+    }
+
+
+    private SessionData load (InputStream is)
+            throws Exception
+    {
+        String id = null;
+
+        try
+        {
+            SessionData data = null;
+            DataInputStream di = new DataInputStream(is);
+
+            id = di.readUTF();
+            String contextPath = di.readUTF();
+            String vhost = di.readUTF();
+            String lastNode = di.readUTF();
+            long created = di.readLong();
+            long accessed = di.readLong();
+            long lastAccessed = di.readLong();
+            long cookieSet = di.readLong();
+            long expiry = di.readLong();
+            long maxIdle = di.readLong();
+
+            data = newSessionData(id, created, accessed, lastAccessed, maxIdle); 
+            data.setContextPath(contextPath);
+            data.setVhost(vhost);
+            data.setLastNode(lastNode);
+            data.setCookieSet(cookieSet);
+            data.setExpiry(expiry);
+            data.setMaxInactiveMs(maxIdle);
+
+            // Attributes
+            restoreAttributes(di, di.readInt(), data);
+
+            return data;        
+        }
+        catch (Exception e)
+        {
+            throw new UnreadableSessionDataException(id, _context, e);
+        }
+    }
+
+    private void restoreAttributes (InputStream is, int size, SessionData data)
+            throws Exception
+    {
+        if (size>0)
+        {
+            // input stream should not be closed here
+            Map<String,Object> attributes = new HashMap<String,Object>();
+            ClassLoadingObjectInputStream ois =  new ClassLoadingObjectInputStream(is);
+            for (int i=0; i<size;i++)
+            {
+                String key = ois.readUTF();
+                Object value = ois.readObject();
+                attributes.put(key,value);
+            }
+            data.putAllAttributes(attributes);
+        }
+    }
+
+
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionManager.java
new file mode 100644
index 0000000..f107957
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionManager.java
@@ -0,0 +1,57 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * FileHashSessionManager
+ *
+ * Session manager that stores its sessions in files on disk
+ * 
+ */
+public class FileSessionManager extends SessionManager
+{
+    protected FileSessionDataStore _sessionDataStore = new FileSessionDataStore();
+
+
+    @Override
+    public void doStart() throws Exception
+    {
+        _sessionStore = new MemorySessionStore();
+        ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
+        
+        super.doStart();
+    }
+
+    @Override
+    public void doStop() throws Exception
+    {
+        super.doStop();
+    }
+    
+    /**
+     * Get the SessionDataStore to configure it
+     * @return
+     */
+    public FileSessionDataStore getSessionDataStore()
+    {
+        return _sessionDataStore;
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
index da34b38..bbabd9f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java
@@ -16,217 +16,63 @@
 //  ========================================================================
 //
 
+
 package org.eclipse.jetty.server.session;
 
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.ConcurrentHashSet;
 
-import org.eclipse.jetty.server.SessionIdManager;
-
-/* ------------------------------------------------------------ */
 /**
- * HashSessionIdManager. An in-memory implementation of the session ID manager.
+ * HashSessionIdManager
+ *
+ *
  */
 public class HashSessionIdManager extends AbstractSessionIdManager
 {
-    private final Map<String, Set<WeakReference<HttpSession>>> _sessions = new HashMap<String, Set<WeakReference<HttpSession>>>();
-
-    /* ------------------------------------------------------------ */
-    public HashSessionIdManager()
-    {
-    }
-
-    /* ------------------------------------------------------------ */
-    public HashSessionIdManager(Random random)
-    {
-        super(random);
-    }
-
-    /* ------------------------------------------------------------ */
     /**
-     * @return Collection of String session IDs
+     * @param server
      */
-    public Collection<String> getSessions()
+    public HashSessionIdManager(Server server)
     {
-        return Collections.unmodifiableCollection(_sessions.keySet());
+        super(server);
     }
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param id the id of the session
-     * @return Collection of Sessions for the passed session ID
-     */
-    public Collection<HttpSession> getSession(String id)
-    {
-        ArrayList<HttpSession> sessions = new ArrayList<HttpSession>();
-        Set<WeakReference<HttpSession>> refs =_sessions.get(id);
-        if (refs!=null)
-        {
-            for (WeakReference<HttpSession> ref: refs)
-            {
-                HttpSession session = ref.get();
-                if (session!=null)
-                    sessions.add(session);
-            }
-        }
-        return sessions;
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doStart() throws Exception
-    {
-        super.doStart();
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doStop() throws Exception
-    {
-        _sessions.clear();
-        super.doStop();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see SessionIdManager#idInUse(String)
-     */
-    @Override
-    public boolean idInUse(String id)
-    {
-        synchronized (this)
-        {
-            return _sessions.containsKey(id);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see SessionIdManager#addSession(HttpSession)
-     */
-    @Override
-    public void addSession(HttpSession session)
-    {
-        String id = getClusterId(session.getId());
-        WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session);
-
-        synchronized (this)
-        {
-            Set<WeakReference<HttpSession>> sessions = _sessions.get(id);
-            if (sessions==null)
-            {
-                sessions=new HashSet<WeakReference<HttpSession>>();
-                _sessions.put(id,sessions);
-            }
-            sessions.add(ref);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see SessionIdManager#removeSession(HttpSession)
-     */
-    @Override
-    public void removeSession(HttpSession session)
-    {
-        String id = getClusterId(session.getId());
-
-        synchronized (this)
-        {
-            Collection<WeakReference<HttpSession>> sessions = _sessions.get(id);
-            if (sessions!=null)
-            {
-                for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
-                {
-                    WeakReference<HttpSession> ref = iter.next();
-                    HttpSession s=ref.get();
-                    if (s==null)
-                    {
-                        iter.remove();
-                        continue;
-                    }
-                    if (s==session)
-                    {
-                        iter.remove();
-                        break;
-                    }
-                }
-                if (sessions.isEmpty())
-                    _sessions.remove(id);
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see SessionIdManager#invalidateAll(String)
-     */
-    @Override
-    public void invalidateAll(String id)
-    {
-        Collection<WeakReference<HttpSession>> sessions;
-        synchronized (this)
-        {
-            sessions = _sessions.remove(id);
-        }
-
-        if (sessions!=null)
-        {
-            for (WeakReference<HttpSession> ref: sessions)
-            {
-                AbstractSession session=(AbstractSession)ref.get();
-                if (session!=null && session.isValid())
-                    session.invalidate();
-            }
-            sessions.clear();
-        }
-    }
+    private final Set<String> _ids = new ConcurrentHashSet<String>();
     
     
-    /* ------------------------------------------------------------ */
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
+     */
     @Override
-    public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
+    public boolean isIdInUse(String id)
     {
-        //generate a new id
-        String newClusterId = newSessionId(request.hashCode());
+         return _ids.contains(id);
+    }
 
 
-        synchronized (this)
-        {
-            Set<WeakReference<HttpSession>> sessions = _sessions.remove(oldClusterId); //get the list of sessions with same id from other contexts
-            if (sessions!=null)
-            {
-                for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
-                {
-                    WeakReference<HttpSession> ref = iter.next();
-                    HttpSession s = ref.get();
-                    if (s == null)
-                    {
-                        continue;
-                    }
-                    else
-                    {
-                        if (s instanceof AbstractSession)
-                        {
-                            AbstractSession abstractSession = (AbstractSession)s;
-                            abstractSession.getSessionManager().renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
-                        }
-                    }
-                }
-                _sessions.put(newClusterId, sessions);
-            }
-        }
+    
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
+     * @param session the session whose id to use
+     */
+    @Override
+    public void useId(Session session)
+    {
+        if (session == null)
+            return;
+        
+       _ids.add(session.getId());
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
+     */
+    @Override
+    public boolean removeId(String id)
+    {
+       return _ids.remove(id);
     }
 
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
index 0039aad..62a6c83 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
@@ -16,677 +16,33 @@
 //  ========================================================================
 //
 
+
 package org.eclipse.jetty.server.session;
 
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
-import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
-
-
-/* ------------------------------------------------------------ */
-/** 
+/**
  * HashSessionManager
- * 
- * An in-memory implementation of SessionManager.
- * <p>
- * This manager supports saving sessions to disk, either periodically or at shutdown.
- * Sessions can also have their content idle saved to disk to reduce the memory overheads of large idle sessions.
- * <p>
- * This manager will create it's own Timer instance to scavenge threads, unless it discovers a shared Timer instance
- * set as the "org.eclipse.jetty.server.session.timer" attribute of the ContextHandler.
  *
+ * In memory-only session manager.
+ * 
  */
-public class HashSessionManager extends AbstractSessionManager
+public class HashSessionManager extends SessionManager
 {
-    final static Logger LOG = SessionHandler.LOG;
-
-    protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>();
-    private Scheduler _timer;
-    private Scheduler.Task _task;
-    long _scavengePeriodMs=30000;
-    long _savePeriodMs=0; //don't do period saves by default
-    long _idleSavePeriodMs = 0; // don't idle save sessions by default.
-    private Scheduler.Task _saveTask;
-    File _storeDir;
-    private boolean _lazyLoad=false;
-    private volatile boolean _sessionsLoaded=false;
-    private boolean _deleteUnrestorableSessions=false;
+    protected NullSessionDataStore _sessionDataStore = new NullSessionDataStore();
 
 
-    /**
-     * Scavenger
-     *
-     */
-    protected class Scavenger implements Runnable
-    {
-        @Override
-        public void run()
-        {
-            try
-            {
-                scavenge();
-            }
-            finally
-            {
-                if (_timer != null && _timer.isRunning()) {
-                    _task = _timer.schedule(this, _scavengePeriodMs, TimeUnit.MILLISECONDS);
-                }
-            }
-        }
-    }
-
-    /**
-     * Saver
-     *
-     */
-    protected class Saver implements Runnable
-    {
-        @Override
-        public void run()
-        {
-            try
-            {
-                saveSessions(true);
-            }
-            catch (Exception e)
-            {       
-                LOG.warn(e);
-            }
-            finally
-            {
-                if (_timer != null && _timer.isRunning())
-                    _saveTask = _timer.schedule(this, _savePeriodMs, TimeUnit.MILLISECONDS);
-            }
-        }        
-    }
-
-
-    /* ------------------------------------------------------------ */
-    public HashSessionManager()
-    {
-        super();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see AbstractSessionManager#doStart()
-     */
     @Override
     public void doStart() throws Exception
     {
-        //try shared scheduler from Server first
-        _timer = getSessionHandler().getServer().getBean(Scheduler.class);
-        if (_timer == null)
-        {
-            //try one passed into the context
-            ServletContext context = ContextHandler.getCurrentContext();
-            if (context!=null)
-                _timer = (Scheduler)context.getAttribute("org.eclipse.jetty.server.session.timer");   
-        }    
-      
-        if (_timer == null)
-        {
-            //make a scheduler if none useable
-            _timer=new ScheduledExecutorScheduler(toString()+"Timer",true);
-            addBean(_timer,true);
-        }
-        else
-            addBean(_timer,false);
+        _sessionStore = new MemorySessionStore();
+        ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
         
         super.doStart();
-
-        setScavengePeriod(getScavengePeriod());
-
-        if (_storeDir!=null)
-        {
-            if (!_storeDir.exists())
-                _storeDir.mkdirs();
-
-            if (!_lazyLoad)
-                restoreSessions();
-        }
-
-        setSavePeriod(getSavePeriod());
     }
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @see AbstractSessionManager#doStop()
-     */
     @Override
     public void doStop() throws Exception
     {
-        // stop the scavengers
-        synchronized(this)
-        {
-            if (_saveTask!=null)
-                _saveTask.cancel();
-
-            _saveTask=null;
-            if (_task!=null)
-                _task.cancel();
-
-            _task=null;
-            _timer=null;
-        }
-       
-
-        // This will callback invalidate sessions - where we decide if we will save
         super.doStop();
-
-        _sessions.clear();
-
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the period in seconds at which a check is made for sessions to be invalidated.
-     */
-    public int getScavengePeriod()
-    {
-        return (int)(_scavengePeriodMs/1000);
-    }
-
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public int getSessions()
-    {
-        int sessions=super.getSessions();
-        if (LOG.isDebugEnabled())
-        {
-            if (_sessions.size()!=sessions)
-                LOG.warn("sessions: "+_sessions.size()+"!="+sessions);
-        }
-        return sessions;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return seconds Idle period after which a session is saved
-     */
-    public int getIdleSavePeriod()
-    {
-      if (_idleSavePeriodMs <= 0)
-        return 0;
-
-      return (int)(_idleSavePeriodMs / 1000);
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Configures the period in seconds after which a session is deemed idle and saved
-     * to save on session memory.
-     *
-     * The session is persisted, the values attribute map is cleared and the session set to idled.
-     *
-     * @param seconds Idle period after which a session is saved
-     */
-    public void setIdleSavePeriod(int seconds)
-    {
-      _idleSavePeriodMs = seconds * 1000L;
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void setMaxInactiveInterval(int seconds)
-    {
-        super.setMaxInactiveInterval(seconds);
-        if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000L)
-            setScavengePeriod((_dftMaxIdleSecs+9)/10);
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param seconds the period is seconds at which sessions are periodically saved to disk
-     */
-    public void setSavePeriod (int seconds)
-    {
-        long period = (seconds * 1000L);
-        if (period < 0)
-            period=0;
-        _savePeriodMs=period;
-
-        if (_timer!=null)
-        {
-            synchronized (this)
-            {
-                if (_saveTask!=null)
-                    _saveTask.cancel();
-                _saveTask = null;
-                if (_savePeriodMs > 0 && _storeDir!=null) //only save if we have a directory configured
-                {
-                    _saveTask = _timer.schedule(new Saver(),_savePeriodMs,TimeUnit.MILLISECONDS);
-                }
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the period in seconds at which sessions are periodically saved to disk
-     */
-    public int getSavePeriod ()
-    {
-        if (_savePeriodMs<=0)
-            return 0;
-
-        return (int)(_savePeriodMs/1000);
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param seconds the period in seconds at which a check is made for sessions to be invalidated.
-     */
-    public void setScavengePeriod(int seconds)
-    { 
-        if (seconds==0)
-            seconds=60;
-
-        long old_period=_scavengePeriodMs;
-        long period=seconds*1000L;
-        if (period>60000)
-            period=60000;
-        if (period<1000)
-            period=1000;
-
-        _scavengePeriodMs=period;
-    
-        synchronized (this)
-        {
-            if (_timer!=null && (period!=old_period || _task==null))
-            {
-                if (_task!=null)
-                {
-                    _task.cancel();
-                    _task = null;
-                }
-
-                _task = _timer.schedule(new Scavenger(),_scavengePeriodMs, TimeUnit.MILLISECONDS);
-            }
-        }
-    }
-
-    /* -------------------------------------------------------------- */
-    /**
-     * Find sessions that have timed out and invalidate them. This runs in the
-     * SessionScavenger thread.
-     */
-    protected void scavenge()
-    {
-        //don't attempt to scavenge if we are shutting down
-        if (isStopping() || isStopped())
-            return;
-
-        Thread thread=Thread.currentThread();
-        ClassLoader old_loader=thread.getContextClassLoader();
-        try
-        {      
-            if (_loader!=null)
-                thread.setContextClassLoader(_loader);
-
-            // For each session
-            long now=System.currentTimeMillis();
-            __log.debug("Scavenging sessions at {}", now); 
-            
-            for (Iterator<HashedSession> i=_sessions.values().iterator(); i.hasNext();)
-            {
-                HashedSession session=i.next();
-                long idleTime=session.getMaxInactiveInterval()*1000L; 
-                if (idleTime>0&&session.getAccessed()+idleTime<now)
-                {
-                    // Found a stale session, add it to the list
-                    try
-                    {
-                        session.timeout();
-                    }
-                    catch (Exception e)
-                    {
-                        __log.warn("Problem scavenging sessions", e);
-                    }
-                }
-                else if (_idleSavePeriodMs > 0 && session.getAccessed()+_idleSavePeriodMs < now)
-                {
-                    try
-                    {
-                        session.idle();
-                    }
-                    catch (Exception e)
-                    {
-                        __log.warn("Problem idling session "+ session.getId(), e);
-                    }
-                }
-            }
-        }       
-        finally
-        {
-            thread.setContextClassLoader(old_loader);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void addSession(AbstractSession session)
-    {
-        if (isRunning())
-            _sessions.put(session.getClusterId(),(HashedSession)session);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public AbstractSession getSession(String idInCluster)
-    {
-        if ( _lazyLoad && !_sessionsLoaded)
-        {
-            try
-            {
-                restoreSessions();
-            }
-            catch(Exception e)
-            {
-                LOG.warn(e);
-            }
-        }
-
-        Map<String,HashedSession> sessions=_sessions;
-        if (sessions==null)
-            return null;
-
-        HashedSession session = sessions.get(idInCluster);
-
-        if (session == null && _lazyLoad)
-            session=restoreSession(idInCluster);
-        if (session == null)
-            return null;
-
-        if (_idleSavePeriodMs!=0)
-            session.deIdle();
-
-        return session;
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void shutdownSessions() throws Exception
-    {   
-        // Invalidate all sessions to cause unbind events
-        ArrayList<HashedSession> sessions=new ArrayList<HashedSession>(_sessions.values());
-        int loop=100;
-        while (sessions.size()>0 && loop-->0)
-        {
-            // If we are called from doStop
-            if (isStopping() && _storeDir != null && _storeDir.exists() && _storeDir.canWrite())
-            {
-                // Then we only save and remove the session from memory- it is not invalidated.
-                for (HashedSession session : sessions)
-                {
-                    session.save(false);
-                    _sessions.remove(session.getClusterId());
-                }
-            }
-            else
-            {
-                for (HashedSession session : sessions)
-                    session.invalidate();
-            }
-
-            // check that no new sessions were created while we were iterating
-            sessions=new ArrayList<HashedSession>(_sessions.values());
-        }
     }
     
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.server.SessionManager#renewSessionId(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
-     */
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
-    {
-        try
-        {
-            Map<String,HashedSession> sessions=_sessions;
-            if (sessions == null)
-                return;
-
-            HashedSession session = sessions.remove(oldClusterId);
-            if (session == null)
-                return;
-
-            session.remove(); //delete any previously saved session
-            session.setClusterId(newClusterId); //update ids
-            session.setNodeId(newNodeId);
-            session.save(); //save updated session: TODO consider only saving file if idled
-            sessions.put(newClusterId, session);
-            
-            super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected AbstractSession newSession(HttpServletRequest request)
-    {
-        return new HashedSession(this, request);
-    }
-
-    /* ------------------------------------------------------------ */
-    protected AbstractSession newSession(long created, long accessed, String clusterId)
-    {
-        return new HashedSession(this, created,accessed, clusterId);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected boolean removeSession(String clusterId)
-    {
-        return _sessions.remove(clusterId)!=null;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void setStoreDirectory (File dir) throws IOException
-    { 
-        // CanonicalFile is used to capture the base store directory in a way that will
-        // work on Windows.  Case differences may through off later checks using this directory.
-        _storeDir=dir.getCanonicalFile();
-    }
-
-    /* ------------------------------------------------------------ */
-    public File getStoreDirectory ()
-    {
-        return _storeDir;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void setLazyLoad(boolean lazyLoad)
-    {
-        _lazyLoad = lazyLoad;
-    }
-
-    /* ------------------------------------------------------------ */
-    public boolean isLazyLoad()
-    {
-        return _lazyLoad;
-    }
-
-    /* ------------------------------------------------------------ */
-    public boolean isDeleteUnrestorableSessions()
-    {
-        return _deleteUnrestorableSessions;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void setDeleteUnrestorableSessions(boolean deleteUnrestorableSessions)
-    {
-        _deleteUnrestorableSessions = deleteUnrestorableSessions;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void restoreSessions () throws Exception
-    {
-        _sessionsLoaded = true;
-
-        if (_storeDir==null || !_storeDir.exists())
-        {
-            return;
-        }
-
-        if (!_storeDir.canRead())
-        {
-            LOG.warn ("Unable to restore Sessions: Cannot read from Session storage directory "+_storeDir.getAbsolutePath());
-            return;
-        }
-
-        String[] files = _storeDir.list();
-        for (int i=0;files!=null&&i<files.length;i++)
-        {
-            restoreSession(files[i]);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    protected synchronized HashedSession restoreSession(String idInCuster)
-    {        
-        File file = new File(_storeDir,idInCuster);
-
-        Exception error = null;
-        if (!file.exists())
-        {
-            if (LOG.isDebugEnabled())
-            {
-                LOG.debug("Not loading: {}",file);
-            }
-            return null;
-        }
-        
-        try (FileInputStream in = new FileInputStream(file))
-        {
-            HashedSession session = restoreSession(in,null);
-            addSession(session,false);
-            session.didActivate();
-            return session;
-        }
-        catch (Exception e)
-        {
-           error = e;
-        }
-        finally
-        {
-            if (error != null)
-            {
-                if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) )
-                {
-                    file.delete();
-                    LOG.warn("Deleting file for unrestorable session {} {}",idInCuster,error);
-                    __log.debug(error);
-                }
-                else
-                {
-                    __log.warn("Problem restoring session {} {}",idInCuster, error);
-                    __log.debug(error);
-                }
-            }
-            else
-            {
-                // delete successfully restored file
-                file.delete();
-            }
-        }
-        return null;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void saveSessions(boolean reactivate) throws Exception
-    {
-        if (_storeDir==null || !_storeDir.exists())
-        {
-            return;
-        }
-
-        if (!_storeDir.canWrite())
-        {
-            LOG.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable");
-            return;
-        }
-
-        for (HashedSession session : _sessions.values())
-            session.save(reactivate);
-    }
-    
-
-    /* ------------------------------------------------------------ */
-    public HashedSession restoreSession (InputStream is, HashedSession session) throws Exception
-    {
-        DataInputStream di = new DataInputStream(is);
-
-        String clusterId = di.readUTF();
-        di.readUTF(); // nodeId
-
-        long created = di.readLong();
-        long accessed = di.readLong();
-        int requests = di.readInt();
-
-        if (session == null)
-            session = (HashedSession)newSession(created, accessed, clusterId);
-        
-        session.setRequests(requests);
-
-        // Attributes
-        int size = di.readInt();
-
-        restoreSessionAttributes(di, size, session);
-
-        try
-        {
-            int maxIdle = di.readInt();
-            session.setMaxInactiveInterval(maxIdle);
-        }
-        catch (IOException e)
-        {
-            LOG.debug("No maxInactiveInterval persisted for session "+clusterId);
-            LOG.ignore(e);
-        }
-
-        return session;
-    }
-
-
-    @SuppressWarnings("resource")
-    private void restoreSessionAttributes (InputStream is, int size, HashedSession session)
-    throws Exception
-    {
-        if (size>0)
-        {
-            // input stream should not be closed here
-            ClassLoadingObjectInputStream ois =  new ClassLoadingObjectInputStream(is);
-            for (int i=0; i<size;i++)
-            {
-                String key = ois.readUTF();
-                Object value = ois.readObject();
-                session.setAttribute(key,value);
-            }
-        }
-    }
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
deleted file mode 100644
index b89c7f9..0000000
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashedSession.java
+++ /dev/null
@@ -1,286 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.server.session;
-
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.util.Enumeration;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-public class HashedSession extends MemSession
-{
-    private static final Logger LOG = Log.getLogger(HashedSession.class);
-
-    private final HashSessionManager _hashSessionManager;
-
-    /** Whether the session has been saved because it has been deemed idle;
-     * in which case its attribute map will have been saved and cleared. */
-    private transient boolean _idled = false;
-
-    /** Whether there has already been an attempt to save this session
-     * which has failed.  If there has, there will be no more save attempts
-     * for this session.  This is to stop the logs being flooded with errors
-     * due to serialization failures that are most likely caused by user
-     * data stored in the session that is not serializable. */
-    private transient boolean _saveFailed = false;
-    
-    /**
-     * True if an attempt has been made to de-idle a session and it failed. Once
-     * true, the session will not be attempted to be de-idled again.
-     */
-    private transient boolean _deIdleFailed = false;
-
-    /* ------------------------------------------------------------- */
-    protected HashedSession(HashSessionManager hashSessionManager, HttpServletRequest request)
-    {
-        super(hashSessionManager,request);
-        _hashSessionManager = hashSessionManager;
-    }
-
-    /* ------------------------------------------------------------- */
-    protected HashedSession(HashSessionManager hashSessionManager, long created, long accessed, String clusterId)
-    {
-        super(hashSessionManager,created, accessed, clusterId);
-        _hashSessionManager = hashSessionManager;
-    }
-
-    /* ------------------------------------------------------------- */
-    protected void checkValid()
-    {
-        if (!_deIdleFailed && _hashSessionManager._idleSavePeriodMs!=0)
-            deIdle();
-        super.checkValid();
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public void setMaxInactiveInterval(int secs)
-    {
-        super.setMaxInactiveInterval(secs);
-        if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000L/10)<_hashSessionManager._scavengePeriodMs)
-            _hashSessionManager.setScavengePeriod((secs+9)/10);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doInvalidate()
-    throws IllegalStateException
-    {
-        super.doInvalidate();
-        remove();
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Remove from the disk
-     */
-    synchronized void remove ()
-    {
-        if (_hashSessionManager._storeDir!=null && getId()!=null)
-        {
-            String id=getId();
-            File f = new File(_hashSessionManager._storeDir, id);
-            f.delete();
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    synchronized void save(boolean reactivate)
-    throws Exception
-    {
-        // Only idle the session if not already idled and no previous save/idle has failed
-        if (!isIdled() && !_saveFailed)
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Saving {} {}",super.getId(),reactivate);
-
-            try
-            {
-                willPassivate();
-                save();
-                if (reactivate)
-                    didActivate();
-                else
-                    clearAttributes();
-            }
-            catch (Exception e)
-            {       
-                LOG.warn("Problem saving session " + super.getId(), e);
-                _idled=false; // assume problem was before _values.clear();
-            }
-        }
-    }
-    
-    
-    
-    synchronized void save ()
-    throws Exception
-    {   
-        File file = null;
-        if (!_saveFailed && _hashSessionManager._storeDir != null)
-        {
-            file = new File(_hashSessionManager._storeDir, super.getId());
-            if (file.exists())
-            {
-                file.delete();
-            }
-
-            try(FileOutputStream fos = new FileOutputStream(file,false))
-            {
-                save(fos);
-            }
-            catch (Exception e)
-            {
-                saveFailed(); // We won't try again for this session
-                if (file != null) 
-                    file.delete(); // No point keeping the file if we didn't save the whole session
-                throw e;             
-            }
-        }
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    public synchronized void save(OutputStream os)  throws IOException
-    {
-        DataOutputStream out = new DataOutputStream(os);
-        out.writeUTF(getClusterId());
-        out.writeUTF(getNodeId());
-        out.writeLong(getCreationTime());
-        out.writeLong(getAccessed());
-
-        /* Don't write these out, as they don't make sense to store because they
-         * either they cannot be true or their value will be restored in the
-         * Session constructor.
-         */
-        //out.writeBoolean(_invalid);
-        //out.writeBoolean(_doInvalidate);
-        //out.writeBoolean( _newSession);
-        out.writeInt(getRequests());
-        out.writeInt(getAttributes());
-        ObjectOutputStream oos = new ObjectOutputStream(out);
-        Enumeration<String> e=getAttributeNames();
-        while(e.hasMoreElements())
-        {
-            String key=e.nextElement();
-            oos.writeUTF(key);
-            oos.writeObject(doGet(key));
-        }
-        
-        out.writeInt(getMaxInactiveInterval());
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized void deIdle()
-    {
-        if (isIdled() && !_deIdleFailed)
-        {
-            // Access now to prevent race with idling period
-            access(System.currentTimeMillis());
-
-            if (LOG.isDebugEnabled())
-                LOG.debug("De-idling " + super.getId());
-
-            FileInputStream fis = null;
-
-            try
-            {
-                File file = new File(_hashSessionManager._storeDir, super.getId());
-                if (!file.exists() || !file.canRead())
-                    throw new FileNotFoundException(file.getName());
-
-                fis = new FileInputStream(file);
-                _idled = false;
-                _hashSessionManager.restoreSession(fis, this);
-                IO.close(fis); 
-                
-                didActivate();
-
-                // If we are doing period saves, then there is no point deleting at this point 
-                if (_hashSessionManager._savePeriodMs == 0)
-                    file.delete();
-            }
-            catch (Exception e)
-            {
-                deIdleFailed();
-                LOG.warn("Problem de-idling session " + super.getId(), e);
-                if (fis != null) IO.close(fis);//Must ensure closed before invalidate
-                invalidate();
-            }
-        }
-    }
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Idle the session to reduce session memory footprint.
-     *
-     * The session is idled by persisting it, then clearing the session values attribute map and finally setting
-     * it to an idled state.
-     * @throws Exception if unable to save session
-     */
-    public synchronized void idle()
-    throws Exception
-    {
-        save(false);
-        _idled = true;
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized boolean isIdled()
-    {
-      return _idled;
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized boolean isSaveFailed()
-    {
-        return _saveFailed;
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized void saveFailed()
-    {
-        _saveFailed = true;
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized void deIdleFailed()
-    {
-        _deIdleFailed = true;
-    }
-    
-    /* ------------------------------------------------------------ */
-    public synchronized boolean isDeIdleFailed()
-    {
-        return _deIdleFailed;
-    }
-}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java
new file mode 100644
index 0000000..d810c19
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java
@@ -0,0 +1,1067 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * JDBCSessionDataStore
+ *
+ * Session data stored in database
+ */
+public class JDBCSessionDataStore extends AbstractSessionDataStore
+{
+    final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    protected boolean _initialized = false;
+    protected Map<String, AtomicInteger> _unloadables = new ConcurrentHashMap<>();
+
+    private DatabaseAdaptor _dbAdaptor;
+    private SessionTableSchema _sessionTableSchema;
+
+    private int _attempts = -1; // <= 0 means unlimited attempts to load a session
+    private boolean _deleteUnloadables = false; //true means if attempts exhausted delete the session
+    private long _gracePeriodMs = 1000L * 60 * 60; //default grace period is 1hr
+
+    /**
+     * SessionTableSchema
+     *
+     */
+    public static class SessionTableSchema
+    {      
+        public final static int MAX_INTERVAL_NOT_SET = -999;
+        
+        protected DatabaseAdaptor _dbAdaptor;
+        protected String _tableName = "JettySessions";
+        protected String _idColumn = "sessionId";
+        protected String _contextPathColumn = "contextPath";
+        protected String _virtualHostColumn = "virtualHost"; 
+        protected String _lastNodeColumn = "lastNode";
+        protected String _accessTimeColumn = "accessTime"; 
+        protected String _lastAccessTimeColumn = "lastAccessTime";
+        protected String _createTimeColumn = "createTime";
+        protected String _cookieTimeColumn = "cookieTime";
+        protected String _lastSavedTimeColumn = "lastSavedTime";
+        protected String _expiryTimeColumn = "expiryTime";
+        protected String _maxIntervalColumn = "maxInterval";
+        protected String _mapColumn = "map";
+
+        
+        
+        protected void setDatabaseAdaptor(DatabaseAdaptor dbadaptor)
+        {
+            _dbAdaptor = dbadaptor;
+        }
+        
+        
+        public String getTableName()
+        {
+            return _tableName;
+        }
+        public void setTableName(String tableName)
+        {
+            checkNotNull(tableName);
+            _tableName = tableName;
+        }
+     
+        public String getIdColumn()
+        {
+            return _idColumn;
+        }
+        public void setIdColumn(String idColumn)
+        {
+            checkNotNull(idColumn);
+            _idColumn = idColumn;
+        }
+        public String getContextPathColumn()
+        {
+            return _contextPathColumn;
+        }
+        public void setContextPathColumn(String contextPathColumn)
+        {
+            checkNotNull(contextPathColumn);
+            _contextPathColumn = contextPathColumn;
+        }
+        public String getVirtualHostColumn()
+        {
+            return _virtualHostColumn;
+        }
+        public void setVirtualHostColumn(String virtualHostColumn)
+        {
+            checkNotNull(virtualHostColumn);
+            _virtualHostColumn = virtualHostColumn;
+        }
+        public String getLastNodeColumn()
+        {
+            return _lastNodeColumn;
+        }
+        public void setLastNodeColumn(String lastNodeColumn)
+        {
+            checkNotNull(lastNodeColumn);
+            _lastNodeColumn = lastNodeColumn;
+        }
+        public String getAccessTimeColumn()
+        {
+            return _accessTimeColumn;
+        }
+        public void setAccessTimeColumn(String accessTimeColumn)
+        {
+            checkNotNull(accessTimeColumn);
+            _accessTimeColumn = accessTimeColumn;
+        }
+        public String getLastAccessTimeColumn()
+        {
+            return _lastAccessTimeColumn;
+        }
+        public void setLastAccessTimeColumn(String lastAccessTimeColumn)
+        {
+            checkNotNull(lastAccessTimeColumn);
+            _lastAccessTimeColumn = lastAccessTimeColumn;
+        }
+        public String getCreateTimeColumn()
+        {
+            return _createTimeColumn;
+        }
+        public void setCreateTimeColumn(String createTimeColumn)
+        {
+            checkNotNull(createTimeColumn);
+            _createTimeColumn = createTimeColumn;
+        }
+        public String getCookieTimeColumn()
+        {
+            return _cookieTimeColumn;
+        }
+        public void setCookieTimeColumn(String cookieTimeColumn)
+        {
+            checkNotNull(cookieTimeColumn);
+            _cookieTimeColumn = cookieTimeColumn;
+        }
+        public String getLastSavedTimeColumn()
+        {
+            return _lastSavedTimeColumn;
+        }
+        public void setLastSavedTimeColumn(String lastSavedTimeColumn)
+        {
+            checkNotNull(lastSavedTimeColumn);
+            _lastSavedTimeColumn = lastSavedTimeColumn;
+        }
+        public String getExpiryTimeColumn()
+        {
+            return _expiryTimeColumn;
+        }
+        public void setExpiryTimeColumn(String expiryTimeColumn)
+        {
+            checkNotNull(expiryTimeColumn);
+            _expiryTimeColumn = expiryTimeColumn;
+        }
+        public String getMaxIntervalColumn()
+        {
+            return _maxIntervalColumn;
+        }
+        public void setMaxIntervalColumn(String maxIntervalColumn)
+        {
+            checkNotNull(maxIntervalColumn);
+            _maxIntervalColumn = maxIntervalColumn;
+        }
+        public String getMapColumn()
+        {
+            return _mapColumn;
+        }
+        public void setMapColumn(String mapColumn)
+        {
+            checkNotNull(mapColumn);
+            _mapColumn = mapColumn;
+        }
+        
+        public String getCreateStatementAsString ()
+        {
+            if (_dbAdaptor == null)
+                throw new IllegalStateException ("No DBAdaptor");
+            
+            String blobType = _dbAdaptor.getBlobType();
+            String longType = _dbAdaptor.getLongType();
+            
+            return "create table "+_tableName+" ("+_idColumn+" varchar(120), "+
+                    _contextPathColumn+" varchar(60), "+_virtualHostColumn+" varchar(60), "+_lastNodeColumn+" varchar(60), "+_accessTimeColumn+" "+longType+", "+
+                    _lastAccessTimeColumn+" "+longType+", "+_createTimeColumn+" "+longType+", "+_cookieTimeColumn+" "+longType+", "+
+                    _lastSavedTimeColumn+" "+longType+", "+_expiryTimeColumn+" "+longType+", "+_maxIntervalColumn+" "+longType+", "+
+                    _mapColumn+" "+blobType+", primary key("+_idColumn+", "+_contextPathColumn+","+_virtualHostColumn+"))";
+        }
+        
+        public String getCreateIndexOverExpiryStatementAsString (String indexName)
+        {
+            return "create index "+indexName+" on "+getTableName()+" ("+getExpiryTimeColumn()+")";
+        }
+        
+        public String getCreateIndexOverSessionStatementAsString (String indexName)
+        {
+            return "create index "+indexName+" on "+getTableName()+" ("+getIdColumn()+", "+getContextPathColumn()+")";
+        }
+        
+        public String getAlterTableForMaxIntervalAsString ()
+        {
+            if (_dbAdaptor == null)
+                throw new IllegalStateException ("No DBAdaptor");
+            String longType = _dbAdaptor.getLongType();
+            String stem = "alter table "+getTableName()+" add "+getMaxIntervalColumn()+" "+longType;
+            if (_dbAdaptor.getDBName().contains("oracle"))
+                return stem + " default "+ MAX_INTERVAL_NOT_SET + " not null";
+            else
+                return stem +" not null default "+ MAX_INTERVAL_NOT_SET;
+        }
+        
+        private void checkNotNull(String s)
+        {
+            if (s == null)
+                throw new IllegalArgumentException(s);
+        }
+        public String getInsertSessionStatementAsString()
+        {
+           return "insert into "+getTableName()+
+            " ("+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+", "+getLastNodeColumn()+
+            ", "+getAccessTimeColumn()+", "+getLastAccessTimeColumn()+", "+getCreateTimeColumn()+", "+getCookieTimeColumn()+
+            ", "+getLastSavedTimeColumn()+", "+getExpiryTimeColumn()+", "+getMaxIntervalColumn()+", "+getMapColumn()+") "+
+            " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+        }
+
+        public PreparedStatement getUpdateSessionStatement(Connection connection, String canonicalContextPath)
+                throws SQLException
+        {
+            String s =  "update "+getTableName()+
+                    " set "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
+                    getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
+                    getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where ";
+
+            if (canonicalContextPath == null || "".equals(canonicalContextPath))
+            {
+                if (_dbAdaptor.isEmptyStringNull())
+                {
+                    s = s+getIdColumn()+" = ? and "+
+                            getContextPathColumn()+" is null and "+
+                            getVirtualHostColumn()+" = ?";
+                    return connection.prepareStatement(s);
+                }
+            }
+
+            return connection.prepareStatement(s+getIdColumn()+" = ? and "+getContextPathColumn()+
+                                               " = ? and "+getVirtualHostColumn()+" = ?");
+        }
+
+      
+        public PreparedStatement getMyExpiredSessionsStatement (Connection connection, String canonicalContextPath, String vhost, long expiry)
+        throws SQLException
+        {
+            if (_dbAdaptor == null)
+                throw new IllegalStateException("No DB adaptor");
+
+
+            if (canonicalContextPath == null || "".equals(canonicalContextPath))
+            {
+                if (_dbAdaptor.isEmptyStringNull())
+                {
+                    PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
+                                                                              " from "+getTableName()+" where "+
+                                                                              getContextPathColumn()+" is null and "+
+                                                                              getVirtualHostColumn()+" = ? and "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
+                    statement.setString(1, vhost);
+                    statement.setLong(2, expiry);
+                    return statement;
+                }
+            }
+
+            PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
+                                                                      " from "+getTableName()+" where "+getContextPathColumn()+" = ? and "+
+                                                                      getVirtualHostColumn()+" = ? and "+
+                                                                      getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
+
+            statement.setString(1, canonicalContextPath);
+            statement.setString(2, vhost);
+            statement.setLong(3, expiry);
+            return statement;
+        }
+      
+    
+        
+        public PreparedStatement getAllAncientExpiredSessionsStatement (Connection connection)
+        throws SQLException
+        {
+            if (_dbAdaptor == null)
+                throw new IllegalStateException("No DB adaptor");
+
+            PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+
+                                                                      " from "+getTableName()+
+                                                                      " where "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
+            return statement;
+        }
+     
+     
+        public PreparedStatement getCheckSessionExistsStatement (Connection connection, String canonicalContextPath)
+        throws SQLException
+        {
+            if (_dbAdaptor == null)
+                throw new IllegalStateException("No DB adaptor");
+
+
+            if (canonicalContextPath == null || "".equals(canonicalContextPath))
+            {
+                if (_dbAdaptor.isEmptyStringNull())
+                {
+                    PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
+                                                                              " from "+getTableName()+
+                                                                              " where "+getIdColumn()+" = ? and "+
+                                                                              getContextPathColumn()+" is null and "+
+                                                                              getVirtualHostColumn()+" = ?");
+                    return statement;
+                }
+            }
+
+            PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
+                                                                      " from "+getTableName()+
+                                                                      " where "+getIdColumn()+" = ? and "+
+                                                                      getContextPathColumn()+" = ? and "+
+                                                                      getVirtualHostColumn()+" = ?");
+            return statement;
+        }
+
+        public void fillCheckSessionExistsStatement (PreparedStatement statement, String id, SessionContext contextId)
+        throws SQLException
+        {
+            statement.clearParameters();
+            ParameterMetaData metaData = statement.getParameterMetaData();
+            if (metaData.getParameterCount() < 3)
+            {
+                statement.setString(1, id);
+                statement.setString(2, contextId.getVhost());
+            }
+            else
+            {
+                statement.setString(1, id);
+                statement.setString(2, contextId.getCanonicalContextPath());
+                statement.setString(3, contextId.getVhost());
+            }
+        }
+        
+        
+        public PreparedStatement getLoadStatement (Connection connection, String id, SessionContext contextId)
+        throws SQLException
+        { 
+            if (_dbAdaptor == null)
+                throw new IllegalStateException("No DB adaptor");
+
+
+            if (contextId.getCanonicalContextPath() == null || "".equals(contextId.getCanonicalContextPath()))
+            {
+                if (_dbAdaptor.isEmptyStringNull())
+                {
+                    PreparedStatement statement = connection.prepareStatement("select * from "+getTableName()+
+                                                                              " where "+getIdColumn()+" = ? and "+
+                                                                              getContextPathColumn()+" is null and "+
+                                                                              getVirtualHostColumn()+" = ?");
+                    statement.setString(1, id);
+                    statement.setString(2, contextId.getVhost());
+
+                    return statement;
+                }
+            }
+
+            PreparedStatement statement = connection.prepareStatement("select * from "+getTableName()+
+                                                                      " where "+getIdColumn()+" = ? and "+getContextPathColumn()+
+                                                                      " = ? and "+getVirtualHostColumn()+" = ?");
+            statement.setString(1, id);
+            statement.setString(2, contextId.getCanonicalContextPath());
+            statement.setString(3, contextId.getVhost());
+
+            return statement;
+        }
+
+        
+        
+        public PreparedStatement getUpdateStatement (Connection connection, String id, SessionContext contextId)
+        throws SQLException
+        {
+            if (_dbAdaptor == null)
+                throw new IllegalStateException("No DB adaptor");
+
+            String s = "update "+getTableName()+
+                    " set "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
+                    getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
+                    getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where ";
+
+            if (contextId.getCanonicalContextPath() == null || "".equals(contextId.getCanonicalContextPath()))
+            {
+                if (_dbAdaptor.isEmptyStringNull())
+                {
+                    PreparedStatement statement = connection.prepareStatement(s+getIdColumn()+" = ? and "+
+                            getContextPathColumn()+" is null and "+
+                            getVirtualHostColumn()+" = ?");
+                    statement.setString(1, id);
+                    statement.setString(2, contextId.getVhost());
+                    return statement;
+                }
+            }
+            PreparedStatement statement = connection.prepareStatement(s+getIdColumn()+" = ? and "+getContextPathColumn()+
+                                                                      " = ? and "+getVirtualHostColumn()+" = ?");
+            statement.setString(1, id);
+            statement.setString(2, contextId.getCanonicalContextPath());
+            statement.setString(3, contextId.getVhost());
+
+            return statement;
+        }
+        
+        
+
+
+        public PreparedStatement getDeleteStatement (Connection connection, String id, SessionContext contextId)
+        throws Exception
+        { 
+            if (_dbAdaptor == null)
+
+                throw new IllegalStateException("No DB adaptor");
+
+
+            if (contextId.getCanonicalContextPath() == null || "".equals(contextId.getCanonicalContextPath()))
+            {
+                if (_dbAdaptor.isEmptyStringNull())
+                {
+                    PreparedStatement statement = connection.prepareStatement("delete from "+getTableName()+
+                                                                              " where "+getIdColumn()+" = ? and "+getContextPathColumn()+
+                                                                              " = ? and "+getVirtualHostColumn()+" = ?");
+                    statement.setString(1, id);
+                    statement.setString(2, contextId.getVhost());
+                    return statement;
+                }
+            }
+
+            PreparedStatement statement = connection.prepareStatement("delete from "+getTableName()+
+                                                                      " where "+getIdColumn()+" = ? and "+getContextPathColumn()+
+                                                                      " = ? and "+getVirtualHostColumn()+" = ?");
+            statement.setString(1, id);
+            statement.setString(2, contextId.getCanonicalContextPath());
+            statement.setString(3, contextId.getVhost());
+
+            return statement;
+
+        }
+
+        
+        /**
+         * Set up the tables in the database
+         * @throws SQLException
+         */
+        /**
+         * @throws SQLException
+         */
+        public void prepareTables()
+        throws SQLException
+        {
+            try (Connection connection = _dbAdaptor.getConnection();
+                 Statement statement = connection.createStatement())
+            {
+                //make the id table
+                connection.setAutoCommit(true);
+                DatabaseMetaData metaData = connection.getMetaData();
+                _dbAdaptor.adaptTo(metaData);
+                    
+                
+                //make the session table if necessary
+                String tableName = _dbAdaptor.convertIdentifier(getTableName());
+                try (ResultSet result = metaData.getTables(null, null, tableName, null))
+                {
+                    if (!result.next())
+                    {
+                        //table does not exist, so create it
+                        statement.executeUpdate(getCreateStatementAsString());
+                    }
+                    else
+                    {
+                        //session table exists, check it has maxinterval column
+                        ResultSet colResult = null;
+                        try
+                        {
+                            colResult = metaData.getColumns(null, null,
+                                                            _dbAdaptor.convertIdentifier(getTableName()), 
+                                                            _dbAdaptor.convertIdentifier(getMaxIntervalColumn()));
+                        }
+                        catch (SQLException s)
+                        {
+                            LOG.warn("Problem checking if "+getTableName()+
+                                     " table contains "+getMaxIntervalColumn()+" column. Ensure table contains column definition: \""
+                                    + getMaxIntervalColumn()+" long not null default -999\"");
+                            throw s;
+                        }
+                        try
+                        {
+                            if (!colResult.next())
+                            {
+                                try
+                                {
+                                    //add the maxinterval column
+                                    statement.executeUpdate(getAlterTableForMaxIntervalAsString());
+                                }
+                                catch (SQLException s)
+                                {
+                                    LOG.warn("Problem adding "+getMaxIntervalColumn()+
+                                             " column. Ensure table contains column definition: \""+getMaxIntervalColumn()+
+                                             " long not null default -999\"");
+                                    throw s;
+                                }
+                            }
+                        }
+                        finally
+                        {
+                            colResult.close();
+                        }
+                    }
+                }
+                //make some indexes on the JettySessions table
+                String index1 = "idx_"+getTableName()+"_expiry";
+                String index2 = "idx_"+getTableName()+"_session";
+
+                boolean index1Exists = false;
+                boolean index2Exists = false;
+                try (ResultSet result = metaData.getIndexInfo(null, null, tableName, false, false))
+                {
+                    while (result.next())
+                    {
+                        String idxName = result.getString("INDEX_NAME");
+                        if (index1.equalsIgnoreCase(idxName))
+                            index1Exists = true;
+                        else if (index2.equalsIgnoreCase(idxName))
+                            index2Exists = true;
+                    }
+                }
+                if (!index1Exists)
+                    statement.executeUpdate(getCreateIndexOverExpiryStatementAsString(index1));
+                if (!index2Exists)
+                    statement.executeUpdate(getCreateIndexOverSessionStatementAsString(index2));
+            }
+        }
+    }
+    
+    
+   
+  
+    public JDBCSessionDataStore ()
+    {
+        super ();
+    }
+
+  
+
+
+
+    @Override
+    protected void doStart() throws Exception
+    {         
+        if (_dbAdaptor == null)
+            throw new IllegalStateException("No jdbc config");
+        
+        _unloadables.clear();
+        initialize();
+        super.doStart();
+    }
+
+
+
+
+    @Override
+    protected void doStop() throws Exception
+    {
+        _unloadables.clear();
+        super.doStop();
+    }
+
+
+
+
+    public void initialize () throws Exception
+    {
+        if (!_initialized)
+        {
+            _initialized = true;
+   
+            //taking the defaults if one not set
+            if (_sessionTableSchema == null)
+                _sessionTableSchema = new SessionTableSchema();
+            
+            _dbAdaptor.initialize();
+            _sessionTableSchema.setDatabaseAdaptor(_dbAdaptor);
+            _sessionTableSchema.prepareTables();
+        }
+    }
+
+
+ 
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(org.eclipse.jetty.server.session.SessionKey)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {
+        if (getLoadAttempts() > 0 && loadAttemptsExhausted(id))
+            throw new UnreadableSessionDataException(id, _context, true);
+            
+        final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        
+        Runnable r = new Runnable()
+        {
+            public void run ()
+            {
+                try (Connection connection = _dbAdaptor.getConnection();
+                     PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _context);
+                     ResultSet result = statement.executeQuery())
+                {
+                    SessionData data = null;
+                    if (result.next())
+                    {                    
+                        data = newSessionData(id,
+                                              result.getLong(_sessionTableSchema.getCreateTimeColumn()), 
+                                              result.getLong(_sessionTableSchema.getAccessTimeColumn()), 
+                                              result.getLong(_sessionTableSchema.getLastAccessTimeColumn()), 
+                                              result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
+                        data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
+                        data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
+                        data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
+                        data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
+                        data.setContextPath(result.getString(_sessionTableSchema.getContextPathColumn())); //TODO needed? this is part of the key now
+                        data.setVhost(result.getString(_sessionTableSchema.getVirtualHostColumn())); //TODO needed??? this is part of the key now
+
+                        try (InputStream is = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
+                             ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
+                        {
+                            Object o = ois.readObject();
+                            data.putAllAttributes((Map<String,Object>)o);
+                        }
+                        catch (Exception e)
+                        {
+                            if (getLoadAttempts() > 0)
+                            {
+                                incLoadAttempt (id);
+                            }
+                            throw new UnreadableSessionDataException (id, _context, e);
+                        }
+                        
+                        //if the session successfully loaded, remove failed attempts
+                        _unloadables.remove(id);
+                        
+                        if (LOG.isDebugEnabled())
+                            LOG.debug("LOADED session {}", data);
+                    }
+                    else
+                        if (LOG.isDebugEnabled())
+                            LOG.debug("No session {}", id);
+                    
+                    reference.set(data);
+                }
+                catch (UnreadableSessionDataException e)
+                {
+                    if (getLoadAttempts() > 0 && loadAttemptsExhausted(id) && isDeleteUnloadableSessions())
+                    {
+                        try
+                        {
+                            delete (id);
+                            _unloadables.remove(id);
+                        }
+                        catch (Exception x)
+                        {
+                            LOG.warn("Problem deleting unloadable session {}", id);
+                        }
+
+                    }
+                    exception.set(e);
+                }
+                catch (Exception e)
+                {
+                    exception.set(e);
+                }
+            }
+        };
+
+        //ensure this runs with context classloader set
+        _context.run(r);
+
+        if (exception.get() != null)
+            throw exception.get();
+
+        return reference.get();
+    }
+
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {
+        try (Connection connection = _dbAdaptor.getConnection();
+             PreparedStatement statement = _sessionTableSchema.getDeleteStatement(connection, id, _context))
+        {
+            connection.setAutoCommit(true);
+            int rows = statement.executeUpdate();
+            if (LOG.isDebugEnabled())
+                LOG.debug("Deleted Session {}:{}",id,(rows>0));
+            
+            return rows > 0;
+        }
+    }
+
+
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        if (data==null || id==null)
+            return;
+
+        if (isNew)
+        {     
+            doInsert(id, data);
+        }
+        else
+        {
+            doUpdate(id, data);            
+        }
+    }
+
+
+    private void doInsert (String id, SessionData data) 
+    throws Exception
+    {
+        String s = _sessionTableSchema.getInsertSessionStatementAsString();
+
+
+        try (Connection connection = _dbAdaptor.getConnection())        
+        {
+            connection.setAutoCommit(true);
+            try  (PreparedStatement statement = connection.prepareStatement(s))
+            {
+                statement.setString(1, id); //session id
+                statement.setString(2, _context.getCanonicalContextPath()); //context path
+                statement.setString(3, _context.getVhost()); //first vhost
+                statement.setString(4, data.getLastNode());//my node id
+                statement.setLong(5, data.getAccessed());//accessTime
+                statement.setLong(6, data.getLastAccessed()); //lastAccessTime
+                statement.setLong(7, data.getCreated()); //time created
+                statement.setLong(8, data.getCookieSet());//time cookie was set
+                statement.setLong(9, data.getLastSaved()); //last saved time
+                statement.setLong(10, data.getExpiry());
+                statement.setLong(11, data.getMaxInactiveMs());
+
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ObjectOutputStream oos = new ObjectOutputStream(baos);
+                oos.writeObject(data.getAllAttributes());
+                oos.flush();
+                byte[] bytes = baos.toByteArray();
+
+                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
+                statement.executeUpdate();
+                if (LOG.isDebugEnabled())
+                    LOG.debug("Inserted session "+data);
+            }
+        }
+    }
+
+    private void doUpdate (String id, SessionData data)
+            throws Exception
+    {
+        try (Connection connection = _dbAdaptor.getConnection())        
+        {
+            connection.setAutoCommit(true);
+            try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, _context.getCanonicalContextPath()))
+            {
+                statement.setString(1, data.getLastNode());//should be my node id
+                statement.setLong(2, data.getAccessed());//accessTime
+                statement.setLong(3, data.getLastAccessed()); //lastAccessTime
+                statement.setLong(4, data.getLastSaved()); //last saved time
+                statement.setLong(5, data.getExpiry());
+                statement.setLong(6, data.getMaxInactiveMs());
+
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                ObjectOutputStream oos = new ObjectOutputStream(baos);
+                oos.writeObject(data.getAllAttributes());
+                oos.flush();
+                byte[] bytes = baos.toByteArray();
+                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+                statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
+
+                if ((_context.getCanonicalContextPath() == null || "".equals(_context.getCanonicalContextPath())) && _dbAdaptor.isEmptyStringNull())
+                {
+                    statement.setString(8, id);
+                    statement.setString(9, _context.getVhost()); 
+                }
+                else
+                {
+                    statement.setString(8, id);
+                    statement.setString(9, _context.getCanonicalContextPath());
+                    statement.setString(10, _context.getVhost());
+                }
+
+                statement.executeUpdate();
+
+                if (LOG.isDebugEnabled())
+                    LOG.debug("Updated session "+data);
+            }
+        }
+    }
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired()
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+        if (LOG.isDebugEnabled())
+            LOG.debug("Getting expired sessions "+System.currentTimeMillis());
+
+        long now = System.currentTimeMillis();
+        
+        
+        Set<String> expiredSessionKeys = new HashSet<>();
+        try (Connection connection = _dbAdaptor.getConnection())
+        {
+            connection.setAutoCommit(true);
+            
+            /*
+             * 1. Select sessions for our node and context that have expired
+             */
+            long upperBound = now;
+            if (LOG.isDebugEnabled())
+                LOG.debug ("{}- Pass 1: Searching for sessions for node {} and context {} expired before {}", _context.getWorkerName(), _context.getCanonicalContextPath(), upperBound);
+
+            try (PreparedStatement statement = _sessionTableSchema.getMyExpiredSessionsStatement(connection, _context.getCanonicalContextPath(), _context.getVhost(), upperBound))
+            {
+                try (ResultSet result = statement.executeQuery())
+                {
+                    while (result.next())
+                    {
+                        String sessionId = result.getString(_sessionTableSchema.getIdColumn());
+                        long exp = result.getLong(_sessionTableSchema.getExpiryTimeColumn());
+                        expiredSessionKeys.add(sessionId);
+                        if (LOG.isDebugEnabled()) LOG.debug (_context.getCanonicalContextPath()+"- Found expired sessionId="+sessionId);
+                    }
+                }
+            }
+
+            /*
+             *  2. Select sessions for any node or context that have expired a long time ago (ie at least 3 grace periods ago)
+             */
+            try (PreparedStatement selectExpiredSessions = _sessionTableSchema.getAllAncientExpiredSessionsStatement(connection))
+            {
+                upperBound = now - (3 * _gracePeriodMs);
+                if (upperBound > 0)
+                {
+                    if (LOG.isDebugEnabled()) LOG.debug("{}- Pass 2: Searching for sessions expired before {}",_context.getWorkerName(), upperBound);
+
+                    selectExpiredSessions.setLong(1, upperBound);
+                    try (ResultSet result = selectExpiredSessions.executeQuery())
+                    {
+                        while (result.next())
+                        {
+                            String sessionId = result.getString(_sessionTableSchema.getIdColumn());
+                            String ctxtpth = result.getString(_sessionTableSchema.getContextPathColumn());
+                            String vh = result.getString(_sessionTableSchema.getVirtualHostColumn());
+                            expiredSessionKeys.add(sessionId);
+                            if (LOG.isDebugEnabled()) LOG.debug ("{}- Found expired sessionId=",_context.getWorkerName(), sessionId);
+                        }
+                    }
+                }
+            }
+            
+
+            Set<String> notExpiredInDB = new HashSet<>();
+            for (String k: candidates)
+            {
+                //there are some keys that the session store thought had expired, but were not
+                //found in our sweep either because it is no longer in the db, or its
+                //expiry time was updated
+                if (!expiredSessionKeys.contains(k))
+                    notExpiredInDB.add(k);
+            }
+
+
+            if (!notExpiredInDB.isEmpty())
+            {
+                //we have some sessions to check
+                try (PreparedStatement checkSessionExists = _sessionTableSchema.getCheckSessionExistsStatement(connection, _context.getCanonicalContextPath()))
+                {
+                    for (String k: notExpiredInDB)
+                    {
+                        _sessionTableSchema.fillCheckSessionExistsStatement (checkSessionExists, k, _context);
+                        try (ResultSet result = checkSessionExists.executeQuery())
+                        {        
+                            if (!result.next())
+                            {
+                                //session doesn't exist any more, can be expired
+                                expiredSessionKeys.add(k);
+                            }
+                            //else its expiry time has not been reached
+                        }
+                        catch (Exception e)
+                        {
+                            LOG.warn("Problem checking if potentially expired session {} exists in db", k,e);
+                        }
+                    }
+
+                }
+            }
+
+            return expiredSessionKeys;
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+            return expiredSessionKeys; //return whatever we got
+        } 
+       
+    }
+    public int getGracePeriodSec ()
+    {
+        return (int)(_gracePeriodMs == 0L? 0 : _gracePeriodMs/1000L);
+    }
+    
+    public void setGracePeriodSec (int sec)
+    {
+        if (sec < 0)
+            _gracePeriodMs = 0;
+        else
+            _gracePeriodMs = sec * 1000L;
+    }
+    
+    public void setDatabaseAdaptor (DatabaseAdaptor dbAdaptor)
+    {
+        checkStarted();
+        _dbAdaptor = dbAdaptor;
+    }
+    
+    public void setSessionTableSchema (SessionTableSchema schema)
+    {
+        checkStarted();
+        _sessionTableSchema = schema;
+    }
+
+    public void setLoadAttempts (int attempts)
+    {
+        checkStarted();
+        _attempts = attempts;
+    }
+
+    public int getLoadAttempts ()
+    {
+        return _attempts;
+    }
+    
+    public boolean loadAttemptsExhausted (String id)
+    {
+        AtomicInteger i = _unloadables.get(id);
+        if (i == null)
+            return false;
+        return (i.get() >= _attempts);
+    }
+    
+    public void setDeleteUnloadableSessions (boolean delete)
+    {
+        checkStarted();
+        _deleteUnloadables = delete;
+    }
+    
+    public boolean isDeleteUnloadableSessions ()
+    {
+        return _deleteUnloadables;
+    }
+    
+    
+    protected void incLoadAttempt (String id)
+    {
+        AtomicInteger i = new AtomicInteger(0);
+        AtomicInteger count = _unloadables.putIfAbsent(id, i);
+        if (count == null)
+            count = i;
+        count.incrementAndGet();
+    }
+    
+  
+    
+    public int getLoadAttempts (String id)
+    {
+        AtomicInteger i = _unloadables.get(id);
+        if (i == null)
+            return 0;
+        return i.get();
+    }
+    
+    public Set<String> getUnloadableSessions ()
+    {
+        return new HashSet<String>(_unloadables.keySet());
+    }
+    
+   public void clearUnloadableSessions()
+   {
+       _unloadables.clear();
+   }
+
+
+
+
+
+   /** 
+    * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+    */
+   @Override
+   public boolean isPassivating()
+   {
+       return true;
+   }
+}
+
+
+
+
+
+
+
+
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
index 3bfb8ba..534f224 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
@@ -18,35 +18,20 @@
 
 package org.eclipse.jetty.server.session;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.sql.Blob;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
-import java.sql.Driver;
-import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.HashSet;
-import java.util.Locale;
 import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
-import javax.naming.InitialContext;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import javax.sql.DataSource;
 
-import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
-import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
-import org.eclipse.jetty.util.thread.Scheduler;
 
 
 
@@ -57,334 +42,19 @@
  * to support distributed sessions.
  *
  */
-public class JDBCSessionIdManager extends AbstractSessionIdManager
+public class JDBCSessionIdManager extends org.eclipse.jetty.server.session.AbstractSessionIdManager
 {
-    final static Logger LOG = SessionHandler.LOG;
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
     public final static int MAX_INTERVAL_NOT_SET = -999;
 
     protected final HashSet<String> _sessionIds = new HashSet<String>();
     protected Server _server;
-    protected Driver _driver;
-    protected String _driverClassName;
-    protected String _connectionUrl;
-    protected DataSource _datasource;
-    protected String _jndiName;
+    protected SessionScavenger _scavenger;
 
-    protected int _deleteBlockSize = 10; //number of ids to include in where 'in' clause
+    private DatabaseAdaptor _dbAdaptor = new DatabaseAdaptor();
 
-    protected Scheduler.Task _task; //scavenge task
-    protected Scheduler _scheduler;
-    protected Scavenger _scavenger;
-    protected boolean _ownScheduler;
-    protected long _lastScavengeTime;
-    protected long _scavengeIntervalMs = 1000L * 60 * 10; //10mins
-
-
-    protected String _createSessionIdTable;
-    protected String _createSessionTable;
-
-    protected String _selectBoundedExpiredSessions;
-    private String _selectExpiredSessions;
-    
-    protected String _insertId;
-    protected String _deleteId;
-    protected String _queryId;
-
-    protected  String _insertSession;
-    protected  String _deleteSession;
-    protected  String _updateSession;
-    protected  String _updateSessionNode;
-    protected  String _updateSessionAccessTime;
-
-    protected DatabaseAdaptor _dbAdaptor = new DatabaseAdaptor();
     protected SessionIdTableSchema _sessionIdTableSchema = new SessionIdTableSchema();
-    protected SessionTableSchema _sessionTableSchema = new SessionTableSchema();
-    
-  
-
- 
-    /**
-     * SessionTableSchema
-     *
-     */
-    public static class SessionTableSchema
-    {        
-        protected DatabaseAdaptor _dbAdaptor;
-        protected String _tableName = "JettySessions";
-        protected String _rowIdColumn = "rowId";
-        protected String _idColumn = "sessionId";
-        protected String _contextPathColumn = "contextPath";
-        protected String _virtualHostColumn = "virtualHost"; 
-        protected String _lastNodeColumn = "lastNode";
-        protected String _accessTimeColumn = "accessTime"; 
-        protected String _lastAccessTimeColumn = "lastAccessTime";
-        protected String _createTimeColumn = "createTime";
-        protected String _cookieTimeColumn = "cookieTime";
-        protected String _lastSavedTimeColumn = "lastSavedTime";
-        protected String _expiryTimeColumn = "expiryTime";
-        protected String _maxIntervalColumn = "maxInterval";
-        protected String _mapColumn = "map";
-        
-        
-        protected void setDatabaseAdaptor(DatabaseAdaptor dbadaptor)
-        {
-            _dbAdaptor = dbadaptor;
-        }
-        
-        
-        public String getTableName()
-        {
-            return _tableName;
-        }
-        public void setTableName(String tableName)
-        {
-            checkNotNull(tableName);
-            _tableName = tableName;
-        }
-        public String getRowIdColumn()
-        {       
-            if ("rowId".equals(_rowIdColumn) && _dbAdaptor.isRowIdReserved())
-                _rowIdColumn = "srowId";
-            return _rowIdColumn;
-        }
-        public void setRowIdColumn(String rowIdColumn)
-        {
-            checkNotNull(rowIdColumn);
-            if (_dbAdaptor == null)
-                throw new IllegalStateException ("DbAdaptor is null");
-            
-            if (_dbAdaptor.isRowIdReserved() && "rowId".equals(rowIdColumn))
-                throw new IllegalArgumentException("rowId is reserved word for Oracle");
-            
-            _rowIdColumn = rowIdColumn;
-        }
-        public String getIdColumn()
-        {
-            return _idColumn;
-        }
-        public void setIdColumn(String idColumn)
-        {
-            checkNotNull(idColumn);
-            _idColumn = idColumn;
-        }
-        public String getContextPathColumn()
-        {
-            return _contextPathColumn;
-        }
-        public void setContextPathColumn(String contextPathColumn)
-        {
-            checkNotNull(contextPathColumn);
-            _contextPathColumn = contextPathColumn;
-        }
-        public String getVirtualHostColumn()
-        {
-            return _virtualHostColumn;
-        }
-        public void setVirtualHostColumn(String virtualHostColumn)
-        {
-            checkNotNull(virtualHostColumn);
-            _virtualHostColumn = virtualHostColumn;
-        }
-        public String getLastNodeColumn()
-        {
-            return _lastNodeColumn;
-        }
-        public void setLastNodeColumn(String lastNodeColumn)
-        {
-            checkNotNull(lastNodeColumn);
-            _lastNodeColumn = lastNodeColumn;
-        }
-        public String getAccessTimeColumn()
-        {
-            return _accessTimeColumn;
-        }
-        public void setAccessTimeColumn(String accessTimeColumn)
-        {
-            checkNotNull(accessTimeColumn);
-            _accessTimeColumn = accessTimeColumn;
-        }
-        public String getLastAccessTimeColumn()
-        {
-            return _lastAccessTimeColumn;
-        }
-        public void setLastAccessTimeColumn(String lastAccessTimeColumn)
-        {
-            checkNotNull(lastAccessTimeColumn);
-            _lastAccessTimeColumn = lastAccessTimeColumn;
-        }
-        public String getCreateTimeColumn()
-        {
-            return _createTimeColumn;
-        }
-        public void setCreateTimeColumn(String createTimeColumn)
-        {
-            checkNotNull(createTimeColumn);
-            _createTimeColumn = createTimeColumn;
-        }
-        public String getCookieTimeColumn()
-        {
-            return _cookieTimeColumn;
-        }
-        public void setCookieTimeColumn(String cookieTimeColumn)
-        {
-            checkNotNull(cookieTimeColumn);
-            _cookieTimeColumn = cookieTimeColumn;
-        }
-        public String getLastSavedTimeColumn()
-        {
-            return _lastSavedTimeColumn;
-        }
-        public void setLastSavedTimeColumn(String lastSavedTimeColumn)
-        {
-            checkNotNull(lastSavedTimeColumn);
-            _lastSavedTimeColumn = lastSavedTimeColumn;
-        }
-        public String getExpiryTimeColumn()
-        {
-            return _expiryTimeColumn;
-        }
-        public void setExpiryTimeColumn(String expiryTimeColumn)
-        {
-            checkNotNull(expiryTimeColumn);
-            _expiryTimeColumn = expiryTimeColumn;
-        }
-        public String getMaxIntervalColumn()
-        {
-            return _maxIntervalColumn;
-        }
-        public void setMaxIntervalColumn(String maxIntervalColumn)
-        {
-            checkNotNull(maxIntervalColumn);
-            _maxIntervalColumn = maxIntervalColumn;
-        }
-        public String getMapColumn()
-        {
-            return _mapColumn;
-        }
-        public void setMapColumn(String mapColumn)
-        {
-            checkNotNull(mapColumn);
-            _mapColumn = mapColumn;
-        }
-        
-        public String getCreateStatementAsString ()
-        {
-            if (_dbAdaptor == null)
-                throw new IllegalStateException ("No DBAdaptor");
-            
-            String blobType = _dbAdaptor.getBlobType();
-            String longType = _dbAdaptor.getLongType();
-            
-            return "create table "+_tableName+" ("+getRowIdColumn()+" varchar(120), "+_idColumn+" varchar(120), "+
-                    _contextPathColumn+" varchar(60), "+_virtualHostColumn+" varchar(60), "+_lastNodeColumn+" varchar(60), "+_accessTimeColumn+" "+longType+", "+
-                    _lastAccessTimeColumn+" "+longType+", "+_createTimeColumn+" "+longType+", "+_cookieTimeColumn+" "+longType+", "+
-                    _lastSavedTimeColumn+" "+longType+", "+_expiryTimeColumn+" "+longType+", "+_maxIntervalColumn+" "+longType+", "+
-                    _mapColumn+" "+blobType+", primary key("+getRowIdColumn()+"))";
-        }
-        
-        public String getCreateIndexOverExpiryStatementAsString (String indexName)
-        {
-            return "create index "+indexName+" on "+getTableName()+" ("+getExpiryTimeColumn()+")";
-        }
-        
-        public String getCreateIndexOverSessionStatementAsString (String indexName)
-        {
-            return "create index "+indexName+" on "+getTableName()+" ("+getIdColumn()+", "+getContextPathColumn()+")";
-        }
-        
-        public String getAlterTableForMaxIntervalAsString ()
-        {
-            if (_dbAdaptor == null)
-                throw new IllegalStateException ("No DBAdaptor");
-            String longType = _dbAdaptor.getLongType();
-            String stem = "alter table "+getTableName()+" add "+getMaxIntervalColumn()+" "+longType;
-            if (_dbAdaptor.getDBName().contains("oracle"))
-                return stem + " default "+ MAX_INTERVAL_NOT_SET + " not null";
-            else
-                return stem +" not null default "+ MAX_INTERVAL_NOT_SET;
-        }
-        
-        private void checkNotNull(String s)
-        {
-            if (s == null)
-                throw new IllegalArgumentException(s);
-        }
-        public String getInsertSessionStatementAsString()
-        {
-           return "insert into "+getTableName()+
-            " ("+getRowIdColumn()+", "+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+", "+getLastNodeColumn()+
-            ", "+getAccessTimeColumn()+", "+getLastAccessTimeColumn()+", "+getCreateTimeColumn()+", "+getCookieTimeColumn()+
-            ", "+getLastSavedTimeColumn()+", "+getExpiryTimeColumn()+", "+getMaxIntervalColumn()+", "+getMapColumn()+") "+
-            " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
-        }
-        public String getDeleteSessionStatementAsString()
-        {
-            return "delete from "+getTableName()+
-            " where "+getRowIdColumn()+" = ?";
-        }
-        public String getUpdateSessionStatementAsString()
-        {
-            return "update "+getTableName()+
-                    " set "+getIdColumn()+" = ?, "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
-                    getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
-                    getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where "+getRowIdColumn()+" = ?";
-        }
-        public String getUpdateSessionNodeStatementAsString()
-        {
-            return "update "+getTableName()+
-                    " set "+getLastNodeColumn()+" = ? where "+getRowIdColumn()+" = ?";
-        }
-        public String getUpdateSessionAccessTimeStatementAsString()
-        {
-           return "update "+getTableName()+
-            " set "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+getLastAccessTimeColumn()+" = ?, "+
-                   getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+getMaxIntervalColumn()+" = ? where "+getRowIdColumn()+" = ?";
-        }
-        
-        public String getBoundedExpiredSessionsStatementAsString()
-        {
-            return "select * from "+getTableName()+" where "+getLastNodeColumn()+" = ? and "+getExpiryTimeColumn()+" >= ? and "+getExpiryTimeColumn()+" <= ?";
-        }
-        
-        public String getSelectExpiredSessionsStatementAsString()
-        {
-            return "select * from "+getTableName()+" where "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?";
-        }
-     
-        public PreparedStatement getLoadStatement (Connection connection, String rowId, String contextPath, String virtualHosts)
-        throws SQLException
-        { 
-            if (_dbAdaptor == null)
-                throw new IllegalStateException("No DB adaptor");
-
-
-            if (contextPath == null || "".equals(contextPath))
-            {
-                if (_dbAdaptor.isEmptyStringNull())
-                {
-                    PreparedStatement statement = connection.prepareStatement("select * from "+getTableName()+
-                                                                              " where "+getIdColumn()+" = ? and "+
-                                                                              getContextPathColumn()+" is null and "+
-                                                                              getVirtualHostColumn()+" = ?");
-                    statement.setString(1, rowId);
-                    statement.setString(2, virtualHosts);
-
-                    return statement;
-                }
-            }
-
-            PreparedStatement statement = connection.prepareStatement("select * from "+getTableName()+
-                                                                      " where "+getIdColumn()+" = ? and "+getContextPathColumn()+
-                                                                      " = ? and "+getVirtualHostColumn()+" = ?");
-            statement.setString(1, rowId);
-            statement.setString(2, contextPath);
-            statement.setString(3, virtualHosts);
-
-            return statement;
-        }
-    }
-    
-    
     
     /**
      * SessionIdTableSchema
@@ -392,14 +62,10 @@
      */
     public static class SessionIdTableSchema
     {
-        protected DatabaseAdaptor _dbAdaptor;
         protected String _tableName = "JettySessionIds";
         protected String _idColumn = "id";
-
-        public void setDatabaseAdaptor(DatabaseAdaptor dbAdaptor)
-        {
-            _dbAdaptor = dbAdaptor;
-        }
+        protected DatabaseAdaptor _jdbc;
+      
         public String getIdColumn()
         {
             return _idColumn;
@@ -442,399 +108,72 @@
             return "create table "+_tableName+" ("+_idColumn+" varchar(120), primary key("+_idColumn+"))";
         }
         
+        protected void prepareTables (DatabaseAdaptor jdbc)
+        throws Exception
+        {
+            _jdbc = jdbc;
+            try (Connection connection = _jdbc.getConnection();
+                 Statement statement = connection.createStatement())
+            {
+                //make the id table
+                connection.setAutoCommit(true);
+                DatabaseMetaData metaData = connection.getMetaData();
+                _jdbc.adaptTo(metaData);
+        
+                
+                //checking for table existence is case-sensitive, but table creation is not
+                String tableName = _jdbc.convertIdentifier(getTableName());
+                try (ResultSet result = metaData.getTables(null, null, tableName, null))
+                {
+                    if (!result.next())
+                    {
+                        //table does not exist, so create it
+                        statement.executeUpdate(getCreateStatementAsString());
+                    }
+                } 
+            }
+        }
+        
         private void checkNotNull(String s)
         {
             if (s == null)
                 throw new IllegalArgumentException(s);
         }
     }
-
-
-    /**
-     * DatabaseAdaptor
-     *
-     * Handles differences between databases.
-     *
-     * Postgres uses the getBytes and setBinaryStream methods to access
-     * a "bytea" datatype, which can be up to 1Gb of binary data. MySQL
-     * is happy to use the "blob" type and getBlob() methods instead.
-     *
-     * TODO if the differences become more major it would be worthwhile
-     * refactoring this class.
-     */
-    public static class DatabaseAdaptor
-    {
-        String _dbName;
-        boolean _isLower;
-        boolean _isUpper;
-        
-        protected String _blobType; //if not set, is deduced from the type of the database at runtime
-        protected String _longType; //if not set, is deduced from the type of the database at runtime
-
-
-        public DatabaseAdaptor ()
-        {           
-        }
-        
-        
-        public void adaptTo(DatabaseMetaData dbMeta)  
-        throws SQLException
-        {
-            _dbName = dbMeta.getDatabaseProductName().toLowerCase(Locale.ENGLISH);
-            if (LOG.isDebugEnabled())
-                LOG.debug ("Using database {}",_dbName);
-            _isLower = dbMeta.storesLowerCaseIdentifiers();
-            _isUpper = dbMeta.storesUpperCaseIdentifiers(); 
-        }
-        
-       
-        public void setBlobType(String blobType)
-        {
-            _blobType = blobType;
-        }
-        
-        public String getBlobType ()
-        {
-            if (_blobType != null)
-                return _blobType;
-
-            if (_dbName.startsWith("postgres"))
-                return "bytea";
-
-            return "blob";
-        }
-        
-
-        public void setLongType(String longType)
-        {
-            _longType = longType;
-        }
-        
-
-        public String getLongType ()
-        {
-            if (_longType != null)
-                return _longType;
-
-            if (_dbName == null)
-                throw new IllegalStateException ("DbAdaptor missing metadata");
-            
-            if (_dbName.startsWith("oracle"))
-                return "number(20)";
-
-            return "bigint";
-        }
-        
-
-        /**
-         * Convert a camel case identifier into either upper or lower
-         * depending on the way the db stores identifiers.
-         *
-         * @param identifier the raw identifier
-         * @return the converted identifier
-         */
-        public String convertIdentifier (String identifier)
-        {
-            if (_dbName == null)
-                throw new IllegalStateException ("DbAdaptor missing metadata");
-            
-            if (_isLower)
-                return identifier.toLowerCase(Locale.ENGLISH);
-            if (_isUpper)
-                return identifier.toUpperCase(Locale.ENGLISH);
-
-            return identifier;
-        }
-
-        public String getDBName ()
-        {
-            return _dbName;
-        }
-
-
-        public InputStream getBlobInputStream (ResultSet result, String columnName)
-        throws SQLException
-        {
-            if (_dbName == null)
-                throw new IllegalStateException ("DbAdaptor missing metadata");
-            
-            if (_dbName.startsWith("postgres"))
-            {
-                byte[] bytes = result.getBytes(columnName);
-                return new ByteArrayInputStream(bytes);
-            }
-
-            Blob blob = result.getBlob(columnName);
-            return blob.getBinaryStream();
-        }
-
-
-        public boolean isEmptyStringNull ()
-        {
-            if (_dbName == null)
-                throw new IllegalStateException ("DbAdaptor missing metadata");
-            
-            return (_dbName.startsWith("oracle"));
-        }
-        
-        /**
-         * rowId is a reserved word for Oracle, so change the name of this column
-         * @return true if db in use is oracle
-         */
-        public boolean isRowIdReserved ()
-        {
-            if (_dbName == null)
-                throw new IllegalStateException ("DbAdaptor missing metadata");
-            
-            return (_dbName != null && _dbName.startsWith("oracle"));
-        }
-    }
-
-    
-    /**
-     * Scavenger
-     *
-     */
-    protected class Scavenger implements Runnable
-    {
-
-        @Override
-        public void run()
-        {
-           try
-           {
-               scavenge();
-           }
-           finally
-           {
-               if (_scheduler != null && _scheduler.isRunning())
-                   _task = _scheduler.schedule(this, _scavengeIntervalMs, TimeUnit.MILLISECONDS);
-           }
-        }
-    }
-
-
+  
+   
     public JDBCSessionIdManager(Server server)
     {
-        super();
-        _server=server;
+        super(server);
     }
 
     public JDBCSessionIdManager(Server server, Random random)
     {
-       super(random);
-       _server=server;
+       super(server,random);
     }
 
-    /**
-     * Configure jdbc connection information via a jdbc Driver
-     *
-     * @param driverClassName the driver classname
-     * @param connectionUrl the driver connection url
-     */
-    public void setDriverInfo (String driverClassName, String connectionUrl)
-    {
-        _driverClassName=driverClassName;
-        _connectionUrl=connectionUrl;
-    }
-
-    /**
-     * Configure jdbc connection information via a jdbc Driver
-     *
-     * @param driverClass the driver class
-     * @param connectionUrl the driver connection url
-     */
-    public void setDriverInfo (Driver driverClass, String connectionUrl)
-    {
-        _driver=driverClass;
-        _connectionUrl=connectionUrl;
-    }
-
-
-    public void setDatasource (DataSource ds)
-    {
-        _datasource = ds;
-    }
-
-    public DataSource getDataSource ()
-    {
-        return _datasource;
-    }
-
-    public String getDriverClassName()
-    {
-        return _driverClassName;
-    }
-
-    public String getConnectionUrl ()
-    {
-        return _connectionUrl;
-    }
-
-    public void setDatasourceName (String jndi)
-    {
-        _jndiName=jndi;
-    }
-
-    public String getDatasourceName ()
-    {
-        return _jndiName;
-    }
-
-    /**
-     * @param name the name of the blob
-     * @deprecated see DbAdaptor.setBlobType
-     */
-    @Deprecated
-    public void setBlobType (String name)
-    {
-        _dbAdaptor.setBlobType(name);
-    }
-
-    public DatabaseAdaptor getDbAdaptor()
-    {
-        return _dbAdaptor;
-    }
-
-    public void setDbAdaptor(DatabaseAdaptor dbAdaptor)
-    {
-        if (dbAdaptor == null)
-            throw new IllegalStateException ("DbAdaptor cannot be null");
-        
-        _dbAdaptor = dbAdaptor;
-    }
-
-    /**
-     * @return the blob type
-     * @deprecated see DbAdaptor.getBlobType
-     */
-    @Deprecated
-    public String getBlobType ()
-    {
-        return _dbAdaptor.getBlobType();
-    }
-
-    /**
-     * @return the long type
-     * @deprecated see DbAdaptor.getLogType
-     */
-    @Deprecated
-    public String getLongType()
-    {
-        return _dbAdaptor.getLongType();
-    }
-
-    /**
-     * @param longType the long type
-     * @deprecated see DbAdaptor.setLongType
-     */
-    @Deprecated
-    public void setLongType(String longType)
-    {
-       _dbAdaptor.setLongType(longType);
-    }
-    
     public SessionIdTableSchema getSessionIdTableSchema()
     {
         return _sessionIdTableSchema;
     }
 
-    public void setSessionIdTableSchema(SessionIdTableSchema sessionIdTableSchema)
-    {
-        if (sessionIdTableSchema == null)
-            throw new IllegalArgumentException("Null SessionIdTableSchema");
-        
-        _sessionIdTableSchema = sessionIdTableSchema;
-    }
 
-    public SessionTableSchema getSessionTableSchema()
-    {
-        return _sessionTableSchema;
-    }
 
-    public void setSessionTableSchema(SessionTableSchema sessionTableSchema)
-    {
-        _sessionTableSchema = sessionTableSchema;
-    }
-
-    public void setDeleteBlockSize (int bsize)
-    {
-        this._deleteBlockSize = bsize;
-    }
-
-    public int getDeleteBlockSize ()
-    {
-        return this._deleteBlockSize;
-    }
     
-    public void setScavengeInterval (long sec)
-    {
-        if (sec<=0)
-            sec=60;
-
-        long old_period=_scavengeIntervalMs;
-        long period=sec*1000L;
-
-        _scavengeIntervalMs=period;
-
-        //add a bit of variability into the scavenge time so that not all
-        //nodes with the same scavenge time sync up
-        long tenPercent = _scavengeIntervalMs/10;
-        if ((System.currentTimeMillis()%2) == 0)
-            _scavengeIntervalMs += tenPercent;
-
-        if (LOG.isDebugEnabled())
-            LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
-        
-        synchronized (this)
-        {
-            //if (_timer!=null && (period!=old_period || _task==null))
-            if (_scheduler != null && (period!=old_period || _task==null))
-            {
-                if (_task!=null)
-                    _task.cancel();
-                if (_scavenger == null)
-                    _scavenger = new Scavenger();
-                _task = _scheduler.schedule(_scavenger,_scavengeIntervalMs,TimeUnit.MILLISECONDS);
-            }
-        }
-    }
-
-    public long getScavengeInterval ()
-    {
-        return _scavengeIntervalMs/1000;
-    }
-
-
+    /** 
+     * Record the session id as being in use
+     * 
+     * @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
+     */
     @Override
-    public void addSession(HttpSession session)
+    public void useId (Session session)
     {
         if (session == null)
             return;
 
         synchronized (_sessionIds)
         {
-            String id = ((JDBCSessionManager.Session)session).getClusterId();
-            try
-            {
-                insert(id);
-                _sessionIds.add(id);
-            }
-            catch (Exception e)
-            {
-                LOG.warn("Problem storing session id="+id, e);
-            }
-        }
-    }
-    
-  
-    public void addSession(String id)
-    {
-        if (id == null)
-            return;
-
-        synchronized (_sessionIds)
-        {           
+            String id = session.getId();
             try
             {
                 insert(id);
@@ -849,22 +188,20 @@
 
 
 
+
+    /** 
+     * Remove the id from in-use set
+     * 
+     * Prevents another context from using this id
+     * 
+     * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
+     */
     @Override
-    public void removeSession(HttpSession session)
-    {
-        if (session == null)
-            return;
-
-        removeSession(((JDBCSessionManager.Session)session).getClusterId());
-    }
-
-
-
-    public void removeSession (String id)
+    public boolean removeId (String id)
     {
 
         if (id == null)
-            return;
+            return false;
 
         synchronized (_sessionIds)
         {
@@ -873,300 +210,17 @@
             try
             {
                 _sessionIds.remove(id);
-                delete(id);
+                return delete(id);
             }
             catch (Exception e)
             {
                 LOG.warn("Problem removing session id="+id, e);
+                return false;
             }
         }
 
     }
 
-
-    @Override
-    public boolean idInUse(String id)
-    {
-        if (id == null)
-            return false;
-
-        String clusterId = getClusterId(id);
-        boolean inUse = false;
-        synchronized (_sessionIds)
-        {
-            inUse = _sessionIds.contains(clusterId);
-        }
-
-        
-        if (inUse)
-            return true; //optimisation - if this session is one we've been managing, we can check locally
-
-        //otherwise, we need to go to the database to check
-        try
-        {
-            return exists(clusterId);
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Problem checking inUse for id="+clusterId, e);
-            return false;
-        }
-    }
-
-    /**
-     * Invalidate the session matching the id on all contexts.
-     *
-     * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
-     */
-    @Override
-    public void invalidateAll(String id)
-    {
-        //take the id out of the list of known sessionids for this node
-        removeSession(id);
-
-        synchronized (_sessionIds)
-        {
-            //tell all contexts that may have a session object with this id to
-            //get rid of them
-            Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-            for (int i=0; contexts!=null && i<contexts.length; i++)
-            {
-                SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-                if (sessionHandler != null)
-                {
-                    SessionManager manager = sessionHandler.getSessionManager();
-
-                    if (manager != null && manager instanceof JDBCSessionManager)
-                    {
-                        ((JDBCSessionManager)manager).invalidateSession(id);
-                    }
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
-    {
-        //generate a new id
-        String newClusterId = newSessionId(request.hashCode());
-
-        synchronized (_sessionIds)
-        {
-            removeSession(oldClusterId);//remove the old one from the list (and database)
-            addSession(newClusterId); //add in the new session id to the list (and database)
-
-            //tell all contexts to update the id 
-            Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-            for (int i=0; contexts!=null && i<contexts.length; i++)
-            {
-                SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-                if (sessionHandler != null) 
-                {
-                    SessionManager manager = sessionHandler.getSessionManager();
-
-                    if (manager != null && manager instanceof JDBCSessionManager)
-                    {
-                        ((JDBCSessionManager)manager).renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
-                    }
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Start up the id manager.
-     *
-     * Makes necessary database tables and starts a Session
-     * scavenger thread.
-     */
-    @Override
-    public void doStart()
-    throws Exception
-    {           
-        initializeDatabase();
-        prepareTables();   
-        super.doStart();
-        if (LOG.isDebugEnabled()) 
-            LOG.debug("Scavenging interval = "+getScavengeInterval()+" sec");
-        
-         //try and use a common scheduler, fallback to own
-         _scheduler =_server.getBean(Scheduler.class);
-         if (_scheduler == null)
-         {
-             _scheduler = new ScheduledExecutorScheduler();
-             _ownScheduler = true;
-             _scheduler.start();
-         }
-         else if (!_scheduler.isStarted())
-             throw new IllegalStateException("Shared scheduler not started");
-  
-        setScavengeInterval(getScavengeInterval());
-    }
-
-    /**
-     * Stop the scavenger.
-     */
-    @Override
-    public void doStop ()
-    throws Exception
-    {
-        synchronized(this)
-        {
-            if (_task!=null)
-                _task.cancel();
-            _task=null;
-            if (_ownScheduler && _scheduler !=null)
-                _scheduler.stop();
-            _scheduler=null;
-        }
-        _sessionIds.clear();
-        super.doStop();
-    }
-
-    /**
-     * Get a connection from the driver or datasource.
-     *
-     * @return the connection for the datasource
-     * @throws SQLException if unable to get the connection
-     */
-    protected Connection getConnection ()
-    throws SQLException
-    {
-        if (_datasource != null)
-            return _datasource.getConnection();
-        else
-            return DriverManager.getConnection(_connectionUrl);
-    }
-
-    /**
-     * Set up the tables in the database
-     * @throws SQLException
-     */
-    /**
-     * @throws SQLException
-     */
-    private void prepareTables()
-    throws SQLException
-    {
-        if (_sessionIdTableSchema == null)
-            throw new IllegalStateException ("No SessionIdTableSchema");
-        
-        if (_sessionTableSchema == null)
-            throw new IllegalStateException ("No SessionTableSchema");
-        
-        try (Connection connection = getConnection();
-             Statement statement = connection.createStatement())
-        {
-            //make the id table
-            connection.setAutoCommit(true);
-            DatabaseMetaData metaData = connection.getMetaData();
-            _dbAdaptor.adaptTo(metaData);
-            _sessionTableSchema.setDatabaseAdaptor(_dbAdaptor);
-            _sessionIdTableSchema.setDatabaseAdaptor(_dbAdaptor);
-            
-            _createSessionIdTable = _sessionIdTableSchema.getCreateStatementAsString();
-            _insertId = _sessionIdTableSchema.getInsertStatementAsString();
-            _deleteId =  _sessionIdTableSchema.getDeleteStatementAsString();
-            _queryId = _sessionIdTableSchema.getSelectStatementAsString();
-            
-            //checking for table existence is case-sensitive, but table creation is not
-            String tableName = _dbAdaptor.convertIdentifier(_sessionIdTableSchema.getTableName());
-            try (ResultSet result = metaData.getTables(null, null, tableName, null))
-            {
-                if (!result.next())
-                {
-                    //table does not exist, so create it
-                    statement.executeUpdate(_createSessionIdTable);
-                }
-            }         
-            
-            //make the session table if necessary
-            tableName = _dbAdaptor.convertIdentifier(_sessionTableSchema.getTableName());
-            try (ResultSet result = metaData.getTables(null, null, tableName, null))
-            {
-                if (!result.next())
-                {
-                    //table does not exist, so create it
-                    _createSessionTable = _sessionTableSchema.getCreateStatementAsString();
-                    statement.executeUpdate(_createSessionTable);
-                }
-                else
-                {
-                    //session table exists, check it has maxinterval column
-                    ResultSet colResult = null;
-                    try
-                    {
-                        colResult = metaData.getColumns(null, null,
-                                                        _dbAdaptor.convertIdentifier(_sessionTableSchema.getTableName()), 
-                                                        _dbAdaptor.convertIdentifier(_sessionTableSchema.getMaxIntervalColumn()));
-                    }
-                    catch (SQLException s)
-                    {
-                        LOG.warn("Problem checking if "+_sessionTableSchema.getTableName()+
-                                 " table contains "+_sessionTableSchema.getMaxIntervalColumn()+" column. Ensure table contains column definition: \""
-                                +_sessionTableSchema.getMaxIntervalColumn()+" long not null default -999\"");
-                        throw s;
-                    }
-                    try
-                    {
-                        if (!colResult.next())
-                        {
-                            try
-                            {
-                                //add the maxinterval column
-                                statement.executeUpdate(_sessionTableSchema.getAlterTableForMaxIntervalAsString());
-                            }
-                            catch (SQLException s)
-                            {
-                                LOG.warn("Problem adding "+_sessionTableSchema.getMaxIntervalColumn()+
-                                         " column. Ensure table contains column definition: \""+_sessionTableSchema.getMaxIntervalColumn()+
-                                         " long not null default -999\"");
-                                throw s;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        colResult.close();
-                    }
-                }
-            }
-            //make some indexes on the JettySessions table
-            String index1 = "idx_"+_sessionTableSchema.getTableName()+"_expiry";
-            String index2 = "idx_"+_sessionTableSchema.getTableName()+"_session";
-
-            boolean index1Exists = false;
-            boolean index2Exists = false;
-            try (ResultSet result = metaData.getIndexInfo(null, null, tableName, false, false))
-            {
-                while (result.next())
-                {
-                    String idxName = result.getString("INDEX_NAME");
-                    if (index1.equalsIgnoreCase(idxName))
-                        index1Exists = true;
-                    else if (index2.equalsIgnoreCase(idxName))
-                        index2Exists = true;
-                }
-            }
-            if (!index1Exists)
-                statement.executeUpdate(_sessionTableSchema.getCreateIndexOverExpiryStatementAsString(index1));
-            if (!index2Exists)
-                statement.executeUpdate(_sessionTableSchema.getCreateIndexOverSessionStatementAsString(index2));
-
-            //set up some strings representing the statements for session manipulation
-            _insertSession = _sessionTableSchema.getInsertSessionStatementAsString();
-            _deleteSession = _sessionTableSchema.getDeleteSessionStatementAsString();
-            _updateSession = _sessionTableSchema.getUpdateSessionStatementAsString();
-            _updateSessionNode = _sessionTableSchema.getUpdateSessionNodeStatementAsString();
-            _updateSessionAccessTime = _sessionTableSchema.getUpdateSessionAccessTimeStatementAsString();
-            _selectBoundedExpiredSessions = _sessionTableSchema.getBoundedExpiredSessionsStatementAsString();
-            _selectExpiredSessions = _sessionTableSchema.getSelectExpiredSessionsStatementAsString();
-        }
-    }
-
     /**
      * Insert a new used session id into the table.
      *
@@ -1176,8 +230,8 @@
     private void insert (String id)
     throws SQLException
     {
-        try (Connection connection = getConnection();
-                PreparedStatement query = connection.prepareStatement(_queryId))
+        try (Connection connection = _dbAdaptor.getConnection();
+             PreparedStatement query = connection.prepareStatement(_sessionIdTableSchema.getSelectStatementAsString()))
         {
             connection.setAutoCommit(true);
             query.setString(1, id);
@@ -1186,7 +240,7 @@
                 //only insert the id if it isn't in the db already
                 if (!result.next())
                 {
-                    try (PreparedStatement statement = connection.prepareStatement(_insertId))
+                    try (PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getInsertStatementAsString()))
                     {
                         statement.setString(1, id);
                         statement.executeUpdate();
@@ -1202,18 +256,18 @@
      * @param id
      * @throws SQLException
      */
-    private void delete (String id)
+    private boolean delete (String id)
     throws SQLException
     {
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_deleteId))
+        try (Connection connection = _dbAdaptor.getConnection();
+             PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getDeleteStatementAsString()))
         {
             connection.setAutoCommit(true);
             statement.setString(1, id);
-            statement.executeUpdate();
+            return (statement.executeUpdate() > 0);
         }
     }
-
+    
 
     /**
      * Check if a session id exists.
@@ -1225,8 +279,8 @@
     private boolean exists (String id)
     throws SQLException
     {
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_queryId))
+        try (Connection connection = _dbAdaptor.getConnection();
+             PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getSelectStatementAsString()))
         {
             connection.setAutoCommit(true);
             statement.setString(1, id);
@@ -1237,325 +291,101 @@
         }
     }
 
-    /**
-     * Look for sessions in the database that have expired.
-     *
-     * We do this in the SessionIdManager and not the SessionManager so
-     * that we only have 1 scavenger, otherwise if there are n SessionManagers
-     * there would be n scavengers, all contending for the database.
-     *
-     * We look first for sessions that expired in the previous interval, then
-     * for sessions that expired previously - these are old sessions that no
-     * node is managing any more and have become stuck in the database.
-     */
-    private void scavenge ()
+
+    @Override
+    public boolean isIdInUse(String id)
     {
-        Set<String> candidateIds = getAllCandidateExpiredSessionIds();
+        if (id == null)
+            return false;
+
+        String sessionId = getId(id);
+        boolean inUse = false;
+        synchronized (_sessionIds)
+        {
+            inUse = _sessionIds.contains(sessionId);
+        }
+
         
-        Connection connection = null;
+        if (inUse)
+            return true; //optimisation - if this session is one we've been managing, we can check locally
+
+        //otherwise, we need to go to the database to check
         try
         {
-            if (LOG.isDebugEnabled())
-                LOG.debug(getWorkerName()+"- Scavenge sweep started at "+System.currentTimeMillis());
-            if (_lastScavengeTime > 0)
-            {
-                connection = getConnection();
-                connection.setAutoCommit(true);
-                Set<String> expiredSessionIds = new HashSet<String>();
-                
-                
-                //Pass 1: find sessions for which we were last managing node that have just expired since last pass
-                long lowerBound = (_lastScavengeTime - _scavengeIntervalMs);
-                long upperBound = _lastScavengeTime;
-                if (LOG.isDebugEnabled())
-                    LOG.debug (getWorkerName()+"- Pass 1: Searching for sessions expired between "+lowerBound + " and "+upperBound);
-
-                try (PreparedStatement statement = connection.prepareStatement(_selectBoundedExpiredSessions))
-                {
-                    statement.setString(1, getWorkerName());
-                    statement.setLong(2, lowerBound);
-                    statement.setLong(3, upperBound);
-                    try (ResultSet result = statement.executeQuery())
-                    {
-                        while (result.next())
-                        {
-                            String sessionId = result.getString(_sessionTableSchema.getIdColumn());
-                            expiredSessionIds.add(sessionId);
-                            if (LOG.isDebugEnabled()) LOG.debug ("Found expired sessionId="+sessionId);
-                        }
-                    }
-                }
-                scavengeSessions(candidateIds, expiredSessionIds, false);
-
-
-                //Pass 2: find sessions that have expired a while ago for which this node was their last manager
-                try (PreparedStatement selectExpiredSessions = connection.prepareStatement(_selectExpiredSessions))
-                {
-                    expiredSessionIds.clear();
-                    upperBound = _lastScavengeTime - (2 * _scavengeIntervalMs);
-                    if (upperBound > 0)
-                    {
-                        if (LOG.isDebugEnabled()) LOG.debug(getWorkerName()+"- Pass 2: Searching for sessions expired before "+upperBound);
-                        selectExpiredSessions.setLong(1, upperBound);
-                        try (ResultSet result = selectExpiredSessions.executeQuery())
-                        {
-                            while (result.next())
-                            {
-                                String sessionId = result.getString(_sessionTableSchema.getIdColumn());
-                                String lastNode = result.getString(_sessionTableSchema.getLastNodeColumn());
-                                if ((getWorkerName() == null && lastNode == null) || (getWorkerName() != null && getWorkerName().equals(lastNode)))
-                                    expiredSessionIds.add(sessionId);
-                                if (LOG.isDebugEnabled()) LOG.debug ("Found expired sessionId="+sessionId+" last managed by "+getWorkerName());
-                            }
-                        }
-                        scavengeSessions(candidateIds, expiredSessionIds, false);
-                    }
-
-
-                    //Pass 3:
-                    //find all sessions that have expired at least a couple of scanIntervals ago
-                    //if we did not succeed in loading them (eg their related context no longer exists, can't be loaded etc) then
-                    //they are simply deleted
-                    upperBound = _lastScavengeTime - (3 * _scavengeIntervalMs);
-                    expiredSessionIds.clear();
-                    if (upperBound > 0)
-                    {
-                        if (LOG.isDebugEnabled()) LOG.debug(getWorkerName()+"- Pass 3: searching for sessions expired before "+upperBound);
-                        selectExpiredSessions.setLong(1, upperBound);
-                        try (ResultSet result = selectExpiredSessions.executeQuery())
-                        {
-                            while (result.next())
-                            {
-                                String sessionId = result.getString(_sessionTableSchema.getIdColumn());
-                                expiredSessionIds.add(sessionId);
-                                if (LOG.isDebugEnabled()) LOG.debug ("Found expired sessionId="+sessionId);
-                            }
-                        }
-                        scavengeSessions(candidateIds, expiredSessionIds, true);
-                    }
-                }
-                
-                //Tell session managers to check remaining sessions in memory that may have expired 
-                //but are no longer in the database
-                scavengeSessions(candidateIds);
-            }
+            return exists(sessionId);
         }
         catch (Exception e)
         {
-            if (isRunning())
-                LOG.warn("Problem selecting expired sessions", e);
-            else
-                LOG.ignore(e);
-        }
-        finally
-        {
-            _lastScavengeTime=System.currentTimeMillis();
-            if (LOG.isDebugEnabled()) LOG.debug(getWorkerName()+"- Scavenge sweep ended at "+_lastScavengeTime);
-            if (connection != null)
-            {
-                try
-                {
-                    connection.close();
-                }
-                catch (SQLException e)
-                {
-                    LOG.warn(e);
-                }
-            }
+            LOG.warn("Problem checking inUse for id="+sessionId, e);
+            return false;
         }
     }
-    
-    
+ 
+
     /**
-     * @param expiredSessionIds
+     * Invalidate the session matching the id on all contexts.
+     *
+     * @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
      */
-    private void scavengeSessions (Set<String> candidateIds, Set<String> expiredSessionIds, boolean forceDelete)
+    @Override
+    public void expireAll(String id)
     {       
-        Set<String> remainingIds = new HashSet<String>(expiredSessionIds);
-        Set<SessionManager> managers = getAllSessionManagers();
-        for (SessionManager m:managers)
+        synchronized (_sessionIds)
         {
-            Set<String> successfullyExpiredIds = ((JDBCSessionManager)m).expire(expiredSessionIds);
-            if (successfullyExpiredIds != null)
-            {
-                remainingIds.removeAll(successfullyExpiredIds);
-                candidateIds.removeAll(successfullyExpiredIds);
-            }
-        }
-    
-
-        //Any remaining ids are of those sessions that no context removed
-        if (!remainingIds.isEmpty() && forceDelete)
-        {
-            LOG.info("Forcibly deleting unrecoverable expired sessions {}", remainingIds);
-            try
-            {
-                //ensure they aren't in the local list of in-use session ids
-                synchronized (_sessionIds)
-                {
-                    _sessionIds.removeAll(remainingIds);
-                }
-                
-                cleanExpiredSessionIds(remainingIds);
-            }
-            catch (Exception e)
-            {
-                LOG.warn("Error removing expired session ids", e);
-            }
+           super.expireAll(id);
         }
     }
+
+
     
+    @Override
+    public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
+    {
+        synchronized (_sessionIds)
+        {
+            super.renewSessionId(oldClusterId, oldNodeId, request);
+        }
+    }
+
     /**
-     * These are the session ids that the session managers thought had 
-     * expired, but were not expired in the database. This could be
-     * because the session is live on another node, or that the
-     * session no longer exists in the database because some other
-     * node removed it.
-     * @param candidateIds
+     * Get the database adaptor in order to configure it
+     * @return
      */
-    private void scavengeSessions (Set<String> candidateIds)
+    public DatabaseAdaptor getDatabaseAdaptor ()
     {
-        if (candidateIds.isEmpty())
-            return;
-        
-        
-        Set<SessionManager> managers = getAllSessionManagers();
-        
-        for (SessionManager m:managers)
-        {
-            //tell the session managers to check the sessions that have expired in memory
-            //if they are no longer in the database, they should be removed
-            ((JDBCSessionManager)m).expireCandidates(candidateIds);
-        }
-    }
-    
-    private Set<String>  getAllCandidateExpiredSessionIds()
-    {
-        HashSet<String> candidateIds = new HashSet<>();
-        
-        Set<SessionManager> managers = getAllSessionManagers();
-        
-        for (SessionManager m:managers)
-        {
-            candidateIds.addAll(((JDBCSessionManager)m).getCandidateExpiredIds());
-        }
-        
-        return candidateIds;
+        return _dbAdaptor;
     }
     
     
-    private Set<SessionManager> getAllSessionManagers()
-    {
-        HashSet<SessionManager> managers = new HashSet<>();
-    
-        Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-        for (int i=0; contexts!=null && i<contexts.length; i++)
-        {
-            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-            if (sessionHandler != null)
-            {
-                SessionManager manager = sessionHandler.getSessionManager();
-                if (manager != null && manager instanceof JDBCSessionManager)
-                    managers.add(manager);
-            }
-        }
-        return managers;
-    }
-
-
-   
-    
-    private void cleanExpiredSessionIds (Set<String> expiredIds)
-    throws Exception
-    {
-        if (expiredIds == null || expiredIds.isEmpty())
-            return;
-        
-        String[] ids = expiredIds.toArray(new String[expiredIds.size()]);
-        try (Connection con = getConnection())
-        {
-            con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
-            con.setAutoCommit(false);
-
-            int start = 0;
-            int end = 0;
-            int blocksize = _deleteBlockSize;
-            int block = 0;
-       
-            try (Statement statement = con.createStatement())
-            {
-                while (end < ids.length)
-                {
-                    start = block*blocksize;
-                    if ((ids.length -  start)  >= blocksize)
-                        end = start + blocksize;
-                    else
-                        end = ids.length;
-
-                    //take them out of the sessionIds table
-                    statement.executeUpdate(fillInClause("delete from "+_sessionIdTableSchema.getTableName()+" where "+_sessionIdTableSchema.getIdColumn()+" in ", ids, start, end));
-                    //take them out of the sessions table
-                    statement.executeUpdate(fillInClause("delete from "+_sessionTableSchema.getTableName()+" where "+_sessionTableSchema.getIdColumn()+" in ", ids, start, end));
-                    block++;
-                }
-            }
-            catch (Exception e)
-            {
-                con.rollback();
-                throw e;
-            }
-            con.commit();
-        }
-    }
-
     
     
     /**
-     * 
-     * @param sql
-     * @param atoms
-     * @throws Exception
+     * Start up the id manager.
+     *
+     * Makes necessary database tables and starts a Session
+     * scavenger thread.
      */
-    private String fillInClause (String sql, String[] literals, int start, int end)
+    @Override
+    public void doStart()
     throws Exception
-    {
-        StringBuffer buff = new StringBuffer();
-        buff.append(sql);
-        buff.append("(");
-        for (int i=start; i<end; i++)
-        {
-            buff.append("'"+(literals[i])+"'");
-            if (i+1<end)
-                buff.append(",");
-        }
-        buff.append(")");
-        return buff.toString();
-    }
-    
-    
-    
-    private void initializeDatabase ()
-    throws Exception
-    {
-        if (_datasource != null)
-            return; //already set up
+    {                
+        _dbAdaptor.initialize();
+        _sessionIdTableSchema.prepareTables(_dbAdaptor);
         
-        if (_jndiName!=null)
-        {
-            InitialContext ic = new InitialContext();
-            _datasource = (DataSource)ic.lookup(_jndiName);
-        }
-        else if ( _driver != null && _connectionUrl != null )
-        {
-            DriverManager.registerDriver(_driver);
-        }
-        else if (_driverClassName != null && _connectionUrl != null)
-        {
-            Class.forName(_driverClassName);
-        }
-        else
-            throw new IllegalStateException("No database configured for sessions");
+        super.doStart();
+      
     }
-    
+
+    /**
+     * Stop
+     */
+    @Override
+    public void doStop ()
+    throws Exception
+    {
+        _sessionIds.clear();
+
+        super.doStop();
+    } 
    
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
index 6962694..13c6a50 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java
@@ -19,1221 +19,56 @@
 
 package org.eclipse.jetty.server.session;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.ObjectOutputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSessionEvent;
-import javax.servlet.http.HttpSessionListener;
-
-import org.eclipse.jetty.server.SessionIdManager;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.server.session.JDBCSessionIdManager.SessionTableSchema;
-import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
 /**
- * JDBCSessionManager.
- * <p>
- * SessionManager that persists sessions to a database to enable clustering.
- * <p>
- * Session data is persisted to the JettySessions table:
- * <dl>
- * <dt>rowId</dt><dd>(unique in cluster: webapp name/path + virtualhost + sessionId)</dd>
- * <dt>contextPath</dt><dd>(of the context owning the session)</dd>
- * <dt>sessionId</dt><dd>(unique in a context)</dd>
- * <dt>lastNode</dt><dd>(name of node last handled session)</dd>
- * <dt>accessTime</dt><dd>(time in milliseconds session was accessed)</dd>
- * <dt>lastAccessTime</dt><dd>(previous time in milliseconds session was accessed)</dd>
- * <dt>createTime</dt><dd>(time in milliseconds session created)</dd>
- * <dt>cookieTime</dt><dd>(time in milliseconds session cookie created)</dd>
- * <dt>lastSavedTime</dt><dd>(last time in milliseconds session access times were saved)</dd>
- * <dt>expiryTime</dt><dd>(time in milliseconds that the session is due to expire)</dd>
- * <dt>map</dt><dd>(attribute map)</dd>
- * </dl>
+ * JDBCSessionManager
  *
- * As an optimization, to prevent thrashing the database, we do not persist
- * the accessTime and lastAccessTime every time the session is accessed. Rather,
- * we write it out every so often. The frequency is controlled by the saveIntervalSec
- * field.
  */
-public class JDBCSessionManager extends AbstractSessionManager
+public class JDBCSessionManager extends SessionManager
 {
-    private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
+  
+    protected DatabaseAdaptor _db;
+    protected JDBCSessionDataStore _sessionDataStore;
 
-    private ConcurrentHashMap<String, Session> _sessions;
-    protected JDBCSessionIdManager _jdbcSessionIdMgr = null;
-    protected long _saveIntervalSec = 60; //only persist changes to session access times every 60 secs
-    protected SessionTableSchema _sessionTableSchema;
-
-   
-
-
-    /**
-     * Session
-     *
-     * Session instance.
-     */
-    public class Session extends MemSession
-    {
-        private static final long serialVersionUID = 5208464051134226143L;
-        
-        /**
-         * If dirty, session needs to be (re)persisted
-         */
-        protected boolean _dirty=false;
-        
-        
-     
-        
-        
-        /**
-         * Time in msec since the epoch that the session will expire
-         */
-        protected long _expiryTime;
-        
-        
-        /**
-         * Time in msec since the epoch that the session was last persisted
-         */
-        protected long _lastSaved;
-        
-        
-        /**
-         * Unique identifier of the last node to host the session
-         */
-        protected String _lastNode;
-        
-        
-        /**
-         * Virtual host for context (used to help distinguish 2 sessions with same id on different contexts)
-         */
-        protected String _virtualHost;
-        
-        
-        /**
-         * Unique row in db for session
-         */
-        protected String _rowId;
-        
-        
-        /**
-         * Mangled context name (used to help distinguish 2 sessions with same id on different contexts)
-         */
-        protected String _canonicalContext;
-        
-   
-        /**
-         * Session from a request.
-         *
-         * @param request the request
-         */
-        protected Session (HttpServletRequest request)
-        {
-            super(JDBCSessionManager.this,request);
-            int maxInterval=getMaxInactiveInterval();
-            _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-            _virtualHost = JDBCSessionManager.getVirtualHost(_context);
-            _canonicalContext = canonicalize(_context.getContextPath());
-            _lastNode = getSessionIdManager().getWorkerName();
-        }
-        
-        
-        /**
-         * Session restored from database
-         * @param sessionId the session id
-         * @param rowId the row id
-         * @param created the created timestamp
-         * @param accessed the access timestamp
-         * @param maxInterval the max inactive interval (in seconds)
-         */
-        protected Session (String sessionId, String rowId, long created, long accessed, long maxInterval)
-        {
-            super(JDBCSessionManager.this, created, accessed, sessionId);
-            _rowId = rowId;
-            super.setMaxInactiveInterval((int)maxInterval); //restore the session's previous inactivity interval setting
-            _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-        }
-        
-        
-        protected synchronized String getRowId()
-        {
-            return _rowId;
-        }
-        
-        protected synchronized void setRowId(String rowId)
-        {
-            _rowId = rowId;
-        }
-        
-        public synchronized void setVirtualHost (String vhost)
-        {
-            _virtualHost=vhost;
-        }
-
-        public synchronized String getVirtualHost ()
-        {
-            return _virtualHost;
-        }
-        
-        public synchronized long getLastSaved ()
-        {
-            return _lastSaved;
-        }
-
-        public synchronized void setLastSaved (long time)
-        {
-            _lastSaved=time;
-        }
-
-        public synchronized void setExpiryTime (long time)
-        {
-            _expiryTime=time;
-        }
-
-        public synchronized long getExpiryTime ()
-        {
-            return _expiryTime;
-        }
-        
-
-        public synchronized void setCanonicalContext(String str)
-        {
-            _canonicalContext=str;
-        }
-
-        public synchronized String getCanonicalContext ()
-        {
-            return _canonicalContext;
-        }
-        
-       
-        public synchronized void setLastNode (String node)
-        {
-            _lastNode=node;
-        }
-
-        public synchronized String getLastNode ()
-        {
-            return _lastNode;
-        }
-
-        @Override
-        public void setAttribute (String name, Object value)
-        {
-            Object old = changeAttribute(name, value);
-            if (value == null && old == null)
-                return; //if same as remove attribute but attribute was already removed, no change
-            
-            _dirty = true;
-        }
-
-        @Override
-        public void removeAttribute (String name)
-        {
-            Object old = changeAttribute(name, null);
-            if (old != null) //only dirty if there was a previous value
-                _dirty=true;
-        }
-
-
-        /**
-         * Entry to session.
-         * Called by SessionHandler on inbound request and the session already exists in this node's memory.
-         *
-         * @see org.eclipse.jetty.server.session.AbstractSession#access(long)
-         */
-        @Override
-        protected boolean access(long time)
-        {
-            synchronized (this)
-            {
-                if (super.access(time))
-                {
-                    int maxInterval=getMaxInactiveInterval();
-                    _expiryTime = (maxInterval <= 0 ? 0 : (time + maxInterval*1000L));
-                    return true;
-                }
-                return false;
-            }
-        }
-        
-        
-        
-
-
-        /** 
-         * Change the max idle time for this session. This recalculates the expiry time.
-         * @see org.eclipse.jetty.server.session.AbstractSession#setMaxInactiveInterval(int)
-         */
-        @Override
-        public void setMaxInactiveInterval(int secs)
-        {
-            synchronized (this)
-            {
-                super.setMaxInactiveInterval(secs);
-                int maxInterval=getMaxInactiveInterval();
-                _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L));
-                //force the session to be written out right now
-                try
-                {
-                    updateSessionAccessTime(this);
-                }
-                catch (Exception e)
-                {
-                    LOG.warn("Problem saving changed max idle time for session "+ this, e);
-                }
-            }
-        }
-
-
-        /**
-         * Exit from session
-         * @see org.eclipse.jetty.server.session.AbstractSession#complete()
-         */
-        @Override
-        protected void complete()
-        {
-            synchronized (this)
-            {
-                super.complete();
-                try
-                {
-                    if (isValid())
-                    {
-                        if (_dirty)
-                        {
-                            //The session attributes have changed, write to the db, ensuring
-                            //http passivation/activation listeners called
-                            save(true);
-                        }
-                        else if ((getAccessed() - _lastSaved) >= (getSaveInterval() * 1000L))
-                        {
-                            updateSessionAccessTime(this);
-                        }
-                    }
-                }
-                catch (Exception e)
-                {
-                    LOG.warn("Problem persisting changed session data id="+getId(), e);
-                }
-                finally
-                {
-                    _dirty=false;
-                }
-            }
-        }
-
-        protected void save() throws Exception
-        {
-            synchronized (this)
-            {
-                try
-                {
-                    updateSession(this);
-                }
-                finally
-                {
-                    _dirty = false;
-                }
-            }
-        }
-
-        protected void save (boolean reactivate) throws Exception
-        {
-            synchronized (this)
-            {
-                if (_dirty)
-                {
-                    //The session attributes have changed, write to the db, ensuring
-                    //http passivation/activation listeners called
-                    willPassivate();                      
-                    updateSession(this);
-                    if (reactivate)
-                        didActivate();  
-                }
-            }
-        }
-
-        
-        @Override
-        protected void timeout() throws IllegalStateException
-        {
-            if (LOG.isDebugEnabled())
-                LOG.debug("Timing out session id="+getClusterId());
-            super.timeout();
-        }
-        
-        
-        @Override
-        public String toString ()
-        {
-            return "Session rowId="+_rowId+",id="+getId()+",lastNode="+_lastNode+
-                            ",created="+getCreationTime()+",accessed="+getAccessed()+
-                            ",lastAccessed="+getLastAccessedTime()+",cookieSet="+getCookieSetTime()+
-                            ",maxInterval="+getMaxInactiveInterval()+",lastSaved="+_lastSaved+",expiry="+_expiryTime;
-        }
-    }
-
-
-
-
-    /**
-     * Set the time in seconds which is the interval between
-     * saving the session access time to the database.
-     *
-     * This is an optimization that prevents the database from
-     * being overloaded when a session is accessed very frequently.
-     *
-     * On session exit, if the session attributes have NOT changed,
-     * the time at which we last saved the accessed
-     * time is compared to the current accessed time. If the interval
-     * is at least saveIntervalSecs, then the access time will be
-     * persisted to the database.
-     *
-     * If any session attribute does change, then the attributes and
-     * the accessed time are persisted.
-     *
-     * @param sec the save interval in seconds
-     */
-    public void setSaveInterval (long sec)
-    {
-        _saveIntervalSec=sec;
-    }
-
-    public long getSaveInterval ()
-    {
-        return _saveIntervalSec;
-    }
-
-
-
-    /**
-     * A method that can be implemented in subclasses to support
-     * distributed caching of sessions. This method will be
-     * called whenever the session is written to the database
-     * because the session data has changed.
-     *
-     * This could be used eg with a JMS backplane to notify nodes
-     * that the session has changed and to delete the session from
-     * the node's cache, and re-read it from the database.
-     * @param session the session to invalidate
-     */
-    public void cacheInvalidate (Session session)
-    {
-
-    }
-
-
-    /**
-     * A session has been requested by its id on this node.
-     *
-     * Load the session by id AND context path from the database.
-     * Multiple contexts may share the same session id (due to dispatching)
-     * but they CANNOT share the same contents.
-     *
-     * Check if last node id is my node id, if so, then the session we have
-     * in memory cannot be stale. If another node used the session last, then
-     * we need to refresh from the db.
-     *
-     * NOTE: this method will go to the database, so if you only want to check
-     * for the existence of a Session in memory, use _sessions.get(id) instead.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
-     */
-    @Override
-    public Session getSession(String idInCluster)
-    {
-        Session session = null;
-        
-        synchronized (this)
-        {
-            Session memSession = (Session)_sessions.get(idInCluster);
-            
-            //check if we need to reload the session -
-            //as an optimization, don't reload on every access
-            //to reduce the load on the database. This introduces a window of
-            //possibility that the node may decide that the session is local to it,
-            //when the session has actually been live on another node, and then
-            //re-migrated to this node. This should be an extremely rare occurrence,
-            //as load-balancers are generally well-behaved and consistently send
-            //sessions to the same node, changing only iff that node fails.
-            //Session data = null;
-            long now = System.currentTimeMillis();
-            if (LOG.isDebugEnabled())
-            {
-                if (memSession==null)
-                    LOG.debug("getSession("+idInCluster+"): not in session map,"+
-                            " now="+now+
-                            " lastSaved="+(memSession==null?0:memSession._lastSaved)+
-                            " interval="+(_saveIntervalSec * 1000L));
-                else
-                    LOG.debug("getSession("+idInCluster+"): in session map, "+
-                            " hashcode="+memSession.hashCode()+
-                            " now="+now+
-                            " lastSaved="+(memSession==null?0:memSession._lastSaved)+
-                            " interval="+(_saveIntervalSec * 1000L)+
-                            " lastNode="+memSession._lastNode+
-                            " thisNode="+getSessionIdManager().getWorkerName()+
-                            " difference="+(now - memSession._lastSaved));
-            }
-
-            try
-            {
-                if (memSession==null)
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("getSession("+idInCluster+"): no session in session map. Reloading session data from db.");
-                    session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
-                }
-                else if ((now - memSession._lastSaved) >= (_saveIntervalSec * 1000L))
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
-                    session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
-                }
-                else
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("getSession("+idInCluster+"): session in session map");
-                    session = memSession;
-                }
-            }
-            catch (Exception e)
-            {
-                LOG.warn("Unable to load session "+idInCluster, e);
-                return null;
-            }
-
-
-            //If we have a session
-            if (session != null)
-            {
-                //If the session was last used on a different node, or session doesn't exist on this node
-                if (!session.getLastNode().equals(getSessionIdManager().getWorkerName()) || memSession==null)
-                {
-                    //if session doesn't expire, or has not already expired, update it and put it in this nodes' memory
-                    if (session._expiryTime <= 0 || session._expiryTime > now)
-                    {
-                        if (LOG.isDebugEnabled()) 
-                            LOG.debug("getSession("+idInCluster+"): lastNode="+session.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName());
-
-                        session.setLastNode(getSessionIdManager().getWorkerName());                            
-                        _sessions.put(idInCluster, session);
-                        _sessionsStats.increment();
-
-                        //update in db
-                        try
-                        {
-                            updateSessionNode(session);
-                            session.didActivate();
-                        }
-                        catch (Exception e)
-                        {
-                            LOG.warn("Unable to update freshly loaded session "+idInCluster, e);
-                            return null;
-                        }
-                    }
-                    else
-                    {
-                        if (LOG.isDebugEnabled())
-                            LOG.debug("getSession ({}): Session has expired", idInCluster);
-                        //ensure that the session id for the expired session is deleted so that a new session with the 
-                        //same id cannot be created (because the idInUse() test would succeed)
-                        _jdbcSessionIdMgr.removeSession(idInCluster);
-                        session=null;
-                    }
-
-                }
-                else
-                {
-                    //the session loaded from the db and the one in memory are the same, so keep using the one in memory
-                    session = memSession;
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("getSession({}): Session not stale {}", idInCluster,session);
-                }
-            }
-            else
-            {
-                if (memSession != null)
-                {
-                    //Session must have been removed from db by another node
-                    removeSession(memSession, true);
-                }
-                //No session in db with matching id and context path.
-                LOG.debug("getSession({}): No session in database matching id={}",idInCluster,idInCluster);
-            }
-
-            return session;
-        }
-    }
     
-
-    /**
-     * Get the number of sessions.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSessions()
-     */
-    @Override
-    public int getSessions()
+    public JDBCSessionManager()
     {
-        return _sessions.size();
+        _db = new DatabaseAdaptor();
+        _sessionStore = new MemorySessionStore();
+        _sessionDataStore = new JDBCSessionDataStore();
     }
 
-
-    /**
-     * Start the session manager.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart()
-     */
     @Override
     public void doStart() throws Exception
     {
-        if (_sessionIdManager==null)
-            throw new IllegalStateException("No session id manager defined");
-
-        _jdbcSessionIdMgr = (JDBCSessionIdManager)_sessionIdManager;
-        _sessionTableSchema = _jdbcSessionIdMgr.getSessionTableSchema();
-
-        _sessions = new ConcurrentHashMap<String, Session>();
-
+        _sessionDataStore.setDatabaseAdaptor(_db);
+        ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
+        
         super.doStart();
     }
 
-
-    /**
-     * Stop the session manager.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStop()
-     */
     @Override
     public void doStop() throws Exception
     {
         super.doStop();
-        _sessions.clear();
-        _sessions = null;
-    }
-
-    @Override
-    protected void shutdownSessions()
-    {
-        //Save the current state of all of our sessions,
-        //do NOT delete them (so other nodes can manage them)
-        long gracefulStopMs = getContextHandler().getServer().getStopTimeout();
-        long stopTime = 0;
-        if (gracefulStopMs > 0)
-            stopTime = System.nanoTime() + (TimeUnit.NANOSECONDS.convert(gracefulStopMs, TimeUnit.MILLISECONDS));        
-
-        ArrayList<Session> sessions = (_sessions == null? new ArrayList<Session>() :new ArrayList<Session>(_sessions.values()) );
-
-        // loop while there are sessions, and while there is stop time remaining, or if no stop time, just 1 loop
-        while (sessions.size() > 0 && ((stopTime > 0 && (System.nanoTime() < stopTime)) || (stopTime == 0)))
-        {
-            for (Session session : sessions)
-            {
-                try
-                {
-                    session.save(false);
-                }
-                catch (Exception e)
-                {
-                    LOG.warn(e);
-                }
-                _sessions.remove(session.getClusterId());
-            }
-
-            //check if we should terminate our loop if we're not using the stop timer
-            if (stopTime == 0)
-                break;
-            
-            // Get any sessions that were added by other requests during processing and go around the loop again
-            sessions=new ArrayList<Session>(_sessions.values());
-        }
     }
 
     
     /**
-     * 
-     * @see org.eclipse.jetty.server.SessionManager#renewSessionId(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
-     */
-    public void renewSessionId (String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
-    {
-        Session session = null;
-        try
-        {
-            session = (Session)_sessions.remove(oldClusterId);
-            if (session != null)
-            {
-                synchronized (session)
-                {
-                    session.setClusterId(newClusterId); //update ids
-                    session.setNodeId(newNodeId);
-                    _sessions.put(newClusterId, session); //put it into list in memory
-                    updateSession(session); //update database
-                }
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn(e);
-        }
-
-        super.renewSessionId(oldClusterId, oldNodeId, newClusterId, newNodeId);
-    }
-
-    
-
-    /**
-     * Invalidate a session.
-     *
-     * @param idInCluster the id in the cluster
-     */
-    protected void invalidateSession (String idInCluster)
-    {
-        Session session = (Session)_sessions.get(idInCluster);
-
-        if (session != null)
-        {
-            session.invalidate();
-        }
-    }
-
-    /**
-     * Delete an existing session, both from the in-memory map and
-     * the database.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
-     */
-    @Override
-    protected boolean removeSession(String idInCluster)
-    {
-        Session session = (Session)_sessions.remove(idInCluster);
-        try
-        {
-            if (session != null)
-                deleteSession(session);
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Problem deleting session id="+idInCluster, e);
-        }
-        return session!=null;
-    }
-
-
-    /**
-     * Add a newly created session to our in-memory list for this node and persist it.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
-     */
-    @Override
-    protected void addSession(AbstractSession session)
-    {
-        if (session==null)
-            return;
-
-        _sessions.put(session.getClusterId(), (Session)session);
-
-        try
-        {
-            synchronized (session)
-            {
-                session.willPassivate();
-                storeSession(((JDBCSessionManager.Session)session));
-                session.didActivate();
-            }
-        }
-        catch (Exception e)
-        {
-            LOG.warn("Unable to store new session id="+session.getId() , e);
-        }
-    }
-
-
-    /**
-     * Make a new Session.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest)
-     */
-    @Override
-    protected AbstractSession newSession(HttpServletRequest request)
-    {
-        return new Session(request);
-    }
-    
-    protected AbstractSession newSession (String sessionId, String rowId, long created, long accessed, long maxInterval)
-    {
-        return new Session(sessionId, rowId, created, accessed, maxInterval);
-    }
-
-    /* ------------------------------------------------------------ */
-    /** Remove session from manager
-     * @param session The session to remove
-     * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
-     * {@link SessionIdManager#invalidateAll(String)} should be called.
-     */
-    @Override
-    public boolean removeSession(AbstractSession session, boolean invalidate)
-    {
-        // Remove session from context and global maps
-        boolean removed = super.removeSession(session, invalidate);
-
-        if (removed)
-        {
-            if (!invalidate)
-            {
-                session.willPassivate();
-            }
-        }
-        
-        return removed;
-    }
-
-
-    /**
-     * Expire any Sessions we have in memory matching the list of
-     * expired Session ids.
-     *
-     * @param sessionIds the session ids to expire
-     * @return the set of successfully expired ids
-     */
-    protected Set<String> expire (Set<String> sessionIds)
-    {
-        //don't attempt to scavenge if we are shutting down
-        if (isStopping() || isStopped())
-            return null;
-
-        
-        Thread thread=Thread.currentThread();
-        ClassLoader old_loader=thread.getContextClassLoader();
-        
-        Set<String> successfullyExpiredIds = new HashSet<String>();
-        try
-        {
-            Iterator<?> itor = sessionIds.iterator();
-            while (itor.hasNext())
-            {
-                String sessionId = (String)itor.next();
-                if (LOG.isDebugEnabled())
-                    LOG.debug("Expiring session id "+sessionId);
-
-                Session session = (Session)_sessions.get(sessionId);
-
-                //if session is not in our memory, then fetch from db so we can call the usual listeners on it
-                if (session == null)
-                {
-                    if (LOG.isDebugEnabled())LOG.debug("Force loading session id "+sessionId);
-                    session = loadSession(sessionId, canonicalize(_context.getContextPath()), getVirtualHost(_context));
-                    if (session != null)
-                    {
-                        //loaded an expired session last managed on this node for this context, add it to the list so we can 
-                        //treat it like a normal expired session
-                        _sessions.put(session.getClusterId(), session);
-                        _sessionsStats.increment();
-                    }
-                    else
-                    {
-                        if (LOG.isDebugEnabled())
-                            LOG.debug("Unrecognized session id="+sessionId);
-                        continue;
-                    }
-                }
-
-                if (session != null)
-                {
-                    session.timeout();
-                    successfullyExpiredIds.add(session.getClusterId());
-                }
-            }
-            return successfullyExpiredIds;
-        }
-        catch (Throwable t)
-        {
-            LOG.warn("Problem expiring sessions", t);
-            return successfullyExpiredIds;
-        }
-        finally
-        {
-            thread.setContextClassLoader(old_loader);
-        }
-    }
-    
-    protected void expireCandidates (Set<String> candidateIds)
-    {
-        Iterator<String> itor = candidateIds.iterator();
-        long now = System.currentTimeMillis();
-        while (itor.hasNext())
-        {
-            String id = itor.next();
-
-            //check if expired in db
-            try
-            {
-                Session memSession = _sessions.get(id);
-                if (memSession == null)
-                {
-                    continue; //no longer in memory
-                }
-
-                Session s = loadSession(id,  canonicalize(_context.getContextPath()), getVirtualHost(_context));
-                if (s == null)
-                {
-                    //session no longer exists, can be safely expired
-                    memSession.timeout();
-                }
-            }
-            catch (Exception e)
-            {
-                LOG.warn("Error checking db for expiry for session {}", id);
-            }
-        }
-    }
-    
-    protected Set<String> getCandidateExpiredIds ()
-    {
-        HashSet<String> expiredIds = new HashSet<>();
-
-        Iterator<String> itor = _sessions.keySet().iterator();
-        while (itor.hasNext())
-        {
-            String id = itor.next();
-            //check to see if session should have expired
-            Session session = _sessions.get(id);
-            if (session._expiryTime > 0 &&  System.currentTimeMillis() > session._expiryTime)
-                expiredIds.add(id);           
-        }
-        return expiredIds;
-    }
-
-
-    /**
-     * Load a session from the database
-     * @param id the id
-     * @param canonicalContextPath the canonical context path
-     * @param vhost the virtual host
-     * @return the session data that was loaded
-     * @throws Exception if unable to load the session
-     */
-    protected Session loadSession (final String id, final String canonicalContextPath, final String vhost)
-    throws Exception
-    {
-        final AtomicReference<Session> _reference = new AtomicReference<Session>();
-        final AtomicReference<Exception> _exception = new AtomicReference<Exception>();
-        Runnable load = new Runnable()
-        {
-            /** 
-             * @see java.lang.Runnable#run()
-             */
-            @SuppressWarnings("unchecked")
-            public void run()
-            {
-                try (Connection connection = getConnection();
-                        PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, canonicalContextPath, vhost);
-                        ResultSet result = statement.executeQuery())
-                {
-                    Session session = null;
-                    if (result.next())
-                    {                    
-                        long maxInterval = result.getLong(_sessionTableSchema.getMaxIntervalColumn());
-                        if (maxInterval == JDBCSessionIdManager.MAX_INTERVAL_NOT_SET)
-                        {
-                            maxInterval = getMaxInactiveInterval(); //if value not saved for maxInactiveInterval, use current value from sessionmanager
-                        }
-                        session = (Session)newSession(id, result.getString(_sessionTableSchema.getRowIdColumn()), 
-                                                  result.getLong(_sessionTableSchema.getCreateTimeColumn()), 
-                                                  result.getLong(_sessionTableSchema.getAccessTimeColumn()), 
-                                                  maxInterval);
-                        session.setCookieSetTime(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
-                        session.setLastAccessedTime(result.getLong(_sessionTableSchema.getLastAccessTimeColumn()));
-                        session.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
-                        session.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
-                        session.setExpiryTime(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
-                        session.setCanonicalContext(result.getString(_sessionTableSchema.getContextPathColumn()));
-                        session.setVirtualHost(result.getString(_sessionTableSchema.getVirtualHostColumn()));
-                                           
-                        try (InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
-                                ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
-                        {
-                            Object o = ois.readObject();
-                            session.addAttributes((Map<String,Object>)o);
-                        }
-
-                        if (LOG.isDebugEnabled())
-                            LOG.debug("LOADED session "+session);
-                    }
-                    else
-                        if (LOG.isDebugEnabled())
-                            LOG.debug("Failed to load session "+id);
-                    _reference.set(session);
-                }
-                catch (Exception e)
-                {
-                    _exception.set(e);
-                }
-            }
-        };
-
-        if (_context==null)
-            load.run();
-        else
-            _context.getContextHandler().handle(null,load);
-
-        if (_exception.get()!=null)
-        {
-            //if the session could not be restored, take its id out of the pool of currently-in-use
-            //session ids
-            _jdbcSessionIdMgr.removeSession(id);
-            throw _exception.get();
-        }
-
-        return _reference.get();
-    }
-
-    /**
-     * Insert a session into the database.
-     *
-     * @param session the session
-     * @throws Exception if unable to store the session
-     */
-    protected void storeSession (Session session)
-    throws Exception
-    {
-        if (session==null)
-            return;
-
-        //put into the database
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._insertSession))
-        {
-            String rowId = calculateRowId(session);
-
-            long now = System.currentTimeMillis();
-            connection.setAutoCommit(true);
-            statement.setString(1, rowId); //rowId
-            statement.setString(2, session.getClusterId()); //session id
-            statement.setString(3, session.getCanonicalContext()); //context path
-            statement.setString(4, session.getVirtualHost()); //first vhost
-            statement.setString(5, getSessionIdManager().getWorkerName());//my node id
-            statement.setLong(6, session.getAccessed());//accessTime
-            statement.setLong(7, session.getLastAccessedTime()); //lastAccessTime
-            statement.setLong(8, session.getCreationTime()); //time created
-            statement.setLong(9, session.getCookieSetTime());//time cookie was set
-            statement.setLong(10, now); //last saved time
-            statement.setLong(11, session.getExpiryTime());
-            statement.setLong(12, session.getMaxInactiveInterval());
-
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(session.getAttributeMap());
-            oos.flush();
-            byte[] bytes = baos.toByteArray();
-
-            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-            statement.setBinaryStream(13, bais, bytes.length);//attribute map as blob
-           
-
-            statement.executeUpdate();
-            session.setRowId(rowId); //set it on the in-memory data as well as in db
-            session.setLastSaved(now);
-        }
-        if (LOG.isDebugEnabled())
-            LOG.debug("Stored session "+session);
-    }
-
-
-    /**
-     * Update data on an existing persisted session.
-     *
-     * @param data the session
-     * @throws Exception if unable to update the session
-     */
-    protected void updateSession (Session data)
-    throws Exception
-    {
-        if (data==null)
-            return;
-
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSession))
-        {
-            long now = System.currentTimeMillis();
-            connection.setAutoCommit(true);
-            statement.setString(1, data.getClusterId());
-            statement.setString(2, getSessionIdManager().getWorkerName());//my node id
-            statement.setLong(3, data.getAccessed());//accessTime
-            statement.setLong(4, data.getLastAccessedTime()); //lastAccessTime
-            statement.setLong(5, now); //last saved time
-            statement.setLong(6, data.getExpiryTime());
-            statement.setLong(7, data.getMaxInactiveInterval());
-
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(data.getAttributeMap());
-            oos.flush();
-            byte[] bytes = baos.toByteArray();
-            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-            statement.setBinaryStream(8, bais, bytes.length);//attribute map as blob
-            statement.setString(9, data.getRowId()); //rowId
-            statement.executeUpdate();
-
-            data.setLastSaved(now);
-        }
-        if (LOG.isDebugEnabled())
-            LOG.debug("Updated session "+data);
-    }
-
-
-    /**
-     * Update the node on which the session was last seen to be my node.
-     *
-     * @param data the session
-     * @throws Exception if unable to update the session node
-     */
-    protected void updateSessionNode (Session data)
-    throws Exception
-    {
-        String nodeId = getSessionIdManager().getWorkerName();
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionNode))
-        {
-            connection.setAutoCommit(true);
-            statement.setString(1, nodeId);
-            statement.setString(2, data.getRowId());
-            statement.executeUpdate();
-        }
-        if (LOG.isDebugEnabled())
-            LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId);
-    }
-
-    /**
-     * Persist the time the session was last accessed.
-     *
-     * @param data the session
-     * @throws Exception
-     */
-    private void updateSessionAccessTime (Session data)
-    throws Exception
-    {
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionAccessTime))
-        {
-            long now = System.currentTimeMillis();
-            connection.setAutoCommit(true);
-            statement.setString(1, getSessionIdManager().getWorkerName());
-            statement.setLong(2, data.getAccessed());
-            statement.setLong(3, data.getLastAccessedTime());
-            statement.setLong(4, now);
-            statement.setLong(5, data.getExpiryTime());
-            statement.setLong(6, data.getMaxInactiveInterval());
-            statement.setString(7, data.getRowId());
-          
-            statement.executeUpdate();
-            data.setLastSaved(now);
-        }
-        if (LOG.isDebugEnabled())
-            LOG.debug("Updated access time session id="+data.getId()+" with lastsaved="+data.getLastSaved());
-    }
-
-
-
-
-    /**
-     * Delete a session from the database. Should only be called
-     * when the session has been invalidated.
-     *
-     * @param data the session data
-     * @throws Exception if unable to delete the session
-     */
-    protected void deleteSession (Session data)
-    throws Exception
-    {
-        try (Connection connection = getConnection();
-                PreparedStatement statement = connection.prepareStatement(_jdbcSessionIdMgr._deleteSession))
-        {
-            connection.setAutoCommit(true);
-            statement.setString(1, data.getRowId());
-            statement.executeUpdate();
-            if (LOG.isDebugEnabled())
-                LOG.debug("Deleted Session "+data);
-        }
-    }
-
-
-
-    /**
-     * Get a connection from the driver.
-     * @return
-     * @throws SQLException
-     */
-    private Connection getConnection ()
-    throws SQLException
-    {
-        return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
-    }
-
-    /**
-     * Calculate a unique id for this session across the cluster.
-     *
-     * Unique id is composed of: contextpath_virtualhost0_sessionid
-     * @param data
+     * Get the db adaptor to configure jdbc settings
      * @return
      */
-    private String calculateRowId (Session data)
+    public DatabaseAdaptor getDatabaseAdaptor()
     {
-        String rowId = canonicalize(_context.getContextPath());
-        rowId = rowId + "_" + getVirtualHost(_context);
-        rowId = rowId+"_"+data.getId();
-        return rowId;
+        return _db;
     }
-
+    
     /**
-     * Get the first virtual host for the context.
-     *
-     * Used to help identify the exact session/contextPath.
-     *
-     * @return 0.0.0.0 if no virtual host is defined
-     */
-    private static String getVirtualHost (ContextHandler.Context context)
-    {
-        String vhost = "0.0.0.0";
-
-        if (context==null)
-            return vhost;
-
-        String [] vhosts = context.getContextHandler().getVirtualHosts();
-        if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
-            return vhost;
-
-        return vhosts[0];
-    }
-
-    /**
-     * Make an acceptable file name from a context path.
-     *
-     * @param path
+     * Get the SessionDataStore to configure it
      * @return
      */
-    private static String canonicalize (String path)
+    public JDBCSessionDataStore getSessionDataStore ()
     {
-        if (path==null)
-            return "";
-
-        return path.replace('/', '_').replace('.','_').replace('\\','_');
+        return _sessionDataStore;
     }
+    
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemSession.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemSession.java
deleted file mode 100644
index b2322d6..0000000
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemSession.java
+++ /dev/null
@@ -1,146 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.server.session;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-
-
-/**
- * MemSession
- *
- * A session whose data is kept in memory
- */
-public class MemSession extends AbstractSession
-{
-
-    private final Map<String,Object> _attributes=new HashMap<String, Object>();
-
-    protected MemSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
-    {
-        super(abstractSessionManager, request);
-    }
-
-    public MemSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
-    {
-        super(abstractSessionManager, created, accessed, clusterId);
-    }
-    
-    
-    /* ------------------------------------------------------------- */
-    @Override
-    public Map<String,Object> getAttributeMap()
-    {
-        return _attributes;
-    }
-   
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public int getAttributes()
-    {
-        synchronized (this)
-        {
-            checkValid();
-            return _attributes.size();
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @SuppressWarnings({ "unchecked" })
-    @Override
-    public Enumeration<String> doGetAttributeNames()
-    {
-        List<String> names=_attributes==null?Collections.EMPTY_LIST:new ArrayList<String>(_attributes.keySet());
-        return Collections.enumeration(names);
-    }
-
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    public Set<String> getNames()
-    {
-        synchronized (this)
-        {
-            return new HashSet<String>(_attributes.keySet());
-        }
-    }
-   
-    
-    /* ------------------------------------------------------------- */
-    @Override
-    public void clearAttributes()
-    {
-        while (_attributes!=null && _attributes.size()>0)
-        {
-            ArrayList<String> keys;
-            synchronized(this)
-            {
-                keys=new ArrayList<String>(_attributes.keySet());
-            }
-
-            Iterator<String> iter=keys.iterator();
-            while (iter.hasNext())
-            {
-                String key=(String)iter.next();
-
-                Object value;
-                synchronized(this)
-                {
-                    value=doPutOrRemove(key,null);
-                }
-                unbindValue(key,value);
-
-                ((AbstractSessionManager)getSessionManager()).doSessionAttributeListeners(this,key,value,null);
-            }
-        }
-        if (_attributes!=null)
-            _attributes.clear();
-    }
-
-    /* ------------------------------------------------------------ */
-    public void addAttributes(Map<String,Object> map)
-    {
-        _attributes.putAll(map);
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    public Object doPutOrRemove(String name, Object value)
-    {
-        return value==null?_attributes.remove(name):_attributes.put(name,value);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public Object doGet(String name)
-    {
-        return _attributes.get(name);
-    }
-    
-}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java
new file mode 100644
index 0000000..9ed3505
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java
@@ -0,0 +1,249 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.statistic.CounterStatistic;
+
+/**
+ * MemorySessionStore
+ *
+ * A session store that keeps its sessions in memory in a hashmap
+ */
+public class MemorySessionStore extends AbstractSessionStore
+{
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    
+    protected ConcurrentHashMap<String, Session> _sessions = new ConcurrentHashMap<String, Session>();
+    
+    private final CounterStatistic _stats = new CounterStatistic();
+    
+    
+    /**
+     * MemorySession
+     *
+     *
+     */
+    public class MemorySession extends Session
+    {
+
+        /**
+         * @param manager
+         * @param request
+         * @param data
+         */
+        public MemorySession(HttpServletRequest request, SessionData data)
+        {
+            super(request, data);
+        }
+        
+        
+        
+
+        /**
+         * @param manager
+         * @param data
+         */
+        public MemorySession(SessionData data)
+        {
+            super(data);
+        }
+    }
+    
+    
+    
+    public MemorySessionStore ()
+    {
+       super();
+    }
+    
+    
+    public long getSessions ()
+    {
+        return _stats.getCurrent();
+    }
+    
+    
+    public long getSessionsMax()
+    {
+        return _stats.getMax();
+    }
+    
+    
+    public long getSessionsTotal()
+    {
+        return _stats.getTotal();
+    }
+    
+    public void resetStats()
+    {
+        _stats.reset();
+    }
+    
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionStore#doGet(java.lang.String)
+     */
+    @Override
+    public Session doGet(String id)
+    {
+        if (id == null)
+            return null;
+        
+        Session session = _sessions.get(id);
+       
+        return session;
+    }
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionStore#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session)
+     */
+    @Override
+    public Session doPutIfAbsent(String id, Session session)
+    {
+        Session s = _sessions.putIfAbsent(id, session);
+        if (s == null)
+            _stats.increment();
+       return s;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionStore#doExists(java.lang.String)
+     */
+    @Override
+    public boolean doExists(String id)
+    {
+       return _sessions.containsKey(id);
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(java.lang.String)
+     */
+    @Override
+    public Session doDelete(String id)
+    {
+        Session s = _sessions.remove(id);
+        if (s != null)
+            _stats.decrement();
+        return  s;
+    }
+    
+    
+
+
+    @Override
+    public Set<String> doGetExpiredCandidates()
+    {
+        Set<String> candidates = new HashSet<String>();
+        long now = System.currentTimeMillis();
+        
+        for (Session s:_sessions.values())
+        {
+            if (s.isExpiredAt(now))
+            {
+                candidates.add(s.getId());
+            }
+        }
+        return candidates;
+    }
+
+
+
+
+
+
+    @Override
+    public void shutdown ()
+    {
+        // loop over all the sessions in memory (a few times if necessary to catch sessions that have been
+        // added while we're running
+        int loop=100;
+        while (!_sessions.isEmpty() && loop-- > 0)
+        {
+            for (Session session: _sessions.values())
+            {
+                //if we have a backing store and the session is dirty make sure it is written out
+                if (_sessionDataStore != null)
+                {
+                    if (session.getSessionData().isDirty())
+                    {
+                        session.willPassivate();
+                        try
+                        {
+                            _sessionDataStore.store(session.getId(), session.getSessionData());
+                        }
+                        catch (Exception e)
+                        {
+                            LOG.warn(e);
+                        }
+                    }
+                    doDelete (session.getId()); //remove from memory
+                }
+                else
+                {
+                    //not preserving sessions on exit
+                    try
+                    {
+                        session.invalidate();
+                    }
+                    catch (Exception e)
+                    {
+                        LOG.ignore(e);
+                    }
+                }
+            }
+        }
+    }
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionStore#newSession(java.lang.String)
+     */
+    @Override
+    public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
+    {
+        MemorySession s =  new MemorySession(request, _sessionDataStore.newSessionData(id, time, time, time, maxInactiveMs));
+        return s;
+    }
+
+
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.SessionData)
+     */
+    @Override
+    public Session newSession(SessionData data)
+    {
+        MemorySession s = new MemorySession (data);
+        return s;
+    }
+
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NeverStaleStrategy.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NeverStaleStrategy.java
new file mode 100644
index 0000000..26a4df9
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NeverStaleStrategy.java
@@ -0,0 +1,40 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * NeverStale
+ *
+ * This strategy says that a session never needs to be refreshed by the cluster.
+ * 
+ */
+public class NeverStaleStrategy implements StalenessStrategy
+{
+
+    /** 
+     * @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
+     */
+    @Override
+    public boolean isStale(Session session)
+    {
+        return false;
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java
new file mode 100644
index 0000000..1104418
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java
@@ -0,0 +1,88 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.Set;
+
+/**
+ * NullSessionDataStore
+ *
+ *
+ */
+public class NullSessionDataStore extends AbstractSessionDataStore
+{
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
+     */
+    @Override
+    public SessionData load(String id) throws Exception
+    {
+        return null;
+    }
+
+    
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
+     */
+    @Override
+    public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
+    {
+        return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
+     */
+    @Override
+    public boolean delete(String id) throws Exception
+    {
+       return true;
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore()
+     */
+    @Override
+    public void doStore(String id, SessionData data, boolean isNew) throws Exception
+    {
+        //noop
+    }
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired()
+     */
+    @Override
+    public Set<String> getExpired(Set<String> candidates)
+    {
+       return candidates; //whatever is suggested we accept
+    }
+
+
+    /** 
+     * @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
+     */
+    @Override
+    public boolean isPassivating()
+    {
+        return false;
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java
new file mode 100644
index 0000000..06694bc
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java
@@ -0,0 +1,754 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionContext;
+import javax.servlet.http.HttpSessionEvent;
+
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.Locker;
+import org.eclipse.jetty.util.thread.Locker.Lock;
+
+
+
+
+/**
+ * Session
+ *
+ *
+ */
+public class Session implements SessionManager.SessionIf
+{
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    
+    public final static String SESSION_CREATED_SECURE="org.eclipse.jetty.security.sessionCreatedSecure";
+    
+    
+    public enum State {VALID, INVALID, INVALIDATING};
+        
+    
+    protected SessionData _sessionData;
+    protected SessionManager _manager;
+    protected String _extendedId; //the _id plus the worker name
+    protected long _requests;
+    private boolean _idChanged;
+    private boolean _newSession;
+    private State _state = State.VALID; //state of the session:valid,invalid or being invalidated
+    private Locker _lock = new Locker();
+    
+    public Session (HttpServletRequest request, SessionData data)
+    {
+        _sessionData = data;
+        _newSession = true;
+        _requests = 1;
+    }
+    
+    
+    public Session (SessionData data)
+    {
+        _sessionData = data;
+        _requests = 1;
+    }
+    
+    
+    public void setSessionManager (SessionManager manager)
+    {
+        _manager = manager;
+    }
+    
+    
+    public void setExtendedId (String extendedId)
+    {
+        _extendedId = extendedId;
+    }
+    
+    /* ------------------------------------------------------------- */
+    protected void cookieSet()
+    {
+        try (Lock lock = lock())
+        {
+           _sessionData.setCookieSet(_sessionData.getAccessed());
+        }
+    }
+    /* ------------------------------------------------------------ */
+    protected boolean access(long time)
+    {
+        try (Lock lock=lock())
+        {
+            if (!isValid())
+                return false;
+            _newSession=false;
+            long lastAccessed = _sessionData.getAccessed();
+            _sessionData.setAccessed(time);
+            _sessionData.setLastAccessed(lastAccessed);
+            int maxInterval=getMaxInactiveInterval();
+           _sessionData.setExpiry(maxInterval <= 0 ? 0 : (time + maxInterval*1000L));
+            if (isExpiredAt(time))
+            {
+                invalidate();
+                return false;
+            }
+            _requests++;
+            return true;
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    protected void complete()
+    {
+        try (Lock lock = lock())
+        {
+            _requests--;
+        }
+    }
+
+    
+
+    /* ------------------------------------------------------------- */
+    /** Check to see if session has expired as at the time given.
+     * @param time the time in milliseconds
+     * @return true if expired
+     */
+    protected boolean isExpiredAt(long time)
+    {
+        try (Lock lock = lock())
+        {
+            return _sessionData.isExpiredAt(time);
+        }
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @param nodename
+     */
+    public void setLastNode (String nodename)
+    {
+        _sessionData.setLastNode(nodename);
+    }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return
+     */
+    public String getLastNode ()
+    {
+        return _sessionData.getLastNode();
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * 
+     */
+    protected void clearAttributes()
+    {
+        Set<String> keys = null;
+
+        do
+        {
+            keys = _sessionData.getKeys();
+            for (String key:keys)
+            {
+                clearAttribute(key);
+            }
+
+        }
+        while (!keys.isEmpty());
+    }
+
+    /* ------------------------------------------------------------ */
+    /** Unset the attribute.
+     * @param name
+     */
+    protected void clearAttribute (String name)
+    {
+        Object old=null;
+        try (Lock lock = lock())
+        {
+            //if session is not valid, don't accept the set
+
+            old=_sessionData.setAttribute(name,null);
+        }
+        if (old == null)
+            return; //if same as remove attribute but attribute was already removed, no change
+        callSessionAttributeListeners(name, null, old);
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Call binding and attribute listeners based on the new and old
+     * values of the attribute.
+     * 
+     * @param name name of the attribute
+     * @param newValue  new value of the attribute
+     * @param oldValue previous value of the attribute
+     */
+    protected void callSessionAttributeListeners (String name, Object newValue, Object oldValue)
+    {
+        if (newValue==null || !newValue.equals(oldValue))
+        {
+            if (oldValue!=null)
+                unbindValue(name,oldValue);
+            if (newValue!=null)
+                bindValue(name,newValue);
+
+            if (_manager == null)
+                throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
+            _manager.doSessionAttributeListeners(this,name,oldValue,newValue);
+        }
+    }
+
+    
+    
+    /* ------------------------------------------------------------- */
+    /**
+     * Unbind value if value implements {@link HttpSessionBindingListener} (calls {@link HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent)}) 
+     * @param name the name with which the object is bound or unbound  
+     * @param value the bound value
+     */
+    public void unbindValue(java.lang.String name, Object value)
+    {
+        if (value!=null&&value instanceof HttpSessionBindingListener)
+            ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
+    }
+    
+
+    /* ------------------------------------------------------------- */
+    /** 
+     * Bind value if value implements {@link HttpSessionBindingListener} (calls {@link HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)}) 
+     * @param name the name with which the object is bound or unbound  
+     * @param value the bound value
+     */
+    public void bindValue(java.lang.String name, Object value)
+    {
+        if (value!=null&&value instanceof HttpSessionBindingListener)
+            ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
+    }
+
+
+    /* ------------------------------------------------------------- */
+    /**
+     * Call the activation listeners. This must be called holding the
+     * _lock.
+     */
+    public void didActivate()
+    {
+        HttpSessionEvent event = new HttpSessionEvent(this);
+        for (Iterator<String> iter = _sessionData.getKeys().iterator(); iter.hasNext();)
+        {
+            Object value = _sessionData.getAttribute(iter.next());
+            if (value instanceof HttpSessionActivationListener)
+            {
+                HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
+                listener.sessionDidActivate(event);
+            }
+        }
+    }
+
+
+    /* ------------------------------------------------------------- */
+    /**
+     * Call the passivation listeners. This must be called holding the
+     * _lock
+     */
+    public void willPassivate()
+    {
+        HttpSessionEvent event = new HttpSessionEvent(this);
+        for (Iterator<String> iter = _sessionData.getKeys().iterator(); iter.hasNext();)
+        {
+            Object value = _sessionData.getAttribute(iter.next());
+            if (value instanceof HttpSessionActivationListener)
+            {
+                HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
+                listener.sessionWillPassivate(event);
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    public boolean isValid()
+    {
+        try (Lock lock = lock())
+        {
+            return _state==State.VALID;
+        }
+    }
+
+
+    /* ------------------------------------------------------------- */
+    public long getCookieSetTime()
+    {
+        try (Lock lock = lock())
+        {
+            return _sessionData.getCookieSet();
+        }
+    }
+
+
+    /* ------------------------------------------------------------- */
+    @Override
+    public long getCreationTime() throws IllegalStateException
+    {
+        try (Lock lock = lock())
+        {
+            checkValid();
+            return _sessionData.getCreated();
+        }
+    }
+
+
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getId()
+     */
+    @Override
+    public String getId()
+    {
+        try (Lock lock = lock())
+        {
+            return _sessionData.getId();
+        }
+    }
+
+    
+    public String getExtendedId()
+    {
+        return _extendedId;
+    }
+    
+    public String getContextPath()
+    {
+        return _sessionData.getContextPath();
+    }
+
+    
+    public String getVHost ()
+    {
+        return _sessionData.getVhost();
+    }
+    
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getLastAccessedTime()
+     */
+    @Override
+    public long getLastAccessedTime()
+    {
+        try (Lock lock = lock())
+        {
+            return _sessionData.getLastAccessed();
+        }
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getServletContext()
+     */
+    @Override
+    public ServletContext getServletContext()
+    {
+        if (_manager == null)
+            throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
+       return _manager._context;
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpSession#setMaxInactiveInterval(int)
+     */
+    @Override
+    public void setMaxInactiveInterval(int secs)
+    {
+        try (Lock lock = lock())
+        {
+            _sessionData.setMaxInactiveMs((long)secs*1000L);  
+            _sessionData.setExpiry(_sessionData.getMaxInactiveMs() <= 0 ? 0 : (System.currentTimeMillis() + _sessionData.getMaxInactiveMs()*1000L));
+            _sessionData.setDirty(true);
+        }
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
+     */
+    @Override
+    public int getMaxInactiveInterval()
+    {
+        try (Lock lock = lock())
+        {
+            return (int)(_sessionData.getMaxInactiveMs()/1000);
+        }
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getSessionContext()
+     */
+    @Override
+    public HttpSessionContext getSessionContext()
+    {
+        checkValid();
+        return SessionManager.__nullSessionContext;
+    }
+
+    
+    public SessionManager getSessionManager()
+    {
+        return _manager;
+    }
+    
+    
+    /* ------------------------------------------------------------- */
+    /**
+     * asserts that the session is valid
+     * @throws IllegalStateException if the session is invalid
+     */
+    protected void checkValid() throws IllegalStateException
+    {    
+        if (!_lock.isLocked())
+            throw new IllegalStateException();
+
+        if (_state != State.VALID)
+            throw new IllegalStateException();
+    }
+
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String)
+     */
+    @Override
+    public Object getAttribute(String name)
+    {
+        try (Lock lock = lock())
+        {
+            checkValid();
+            return _sessionData.getAttribute(name);
+        }
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getValue(java.lang.String)
+     */
+    @Override
+    public Object getValue(String name)
+    {
+        try (Lock lock = lock())
+        { 
+            return _sessionData.getAttribute(name);
+        }
+    }
+
+    /** 
+     * @see javax.servlet.http.HttpSession#getAttributeNames()
+     */
+    @Override
+    public Enumeration<String> getAttributeNames()
+    {
+        try (Lock lock = lock())
+        {
+            checkValid();
+            final Iterator<String> itor = _sessionData.getKeys().iterator();
+            return new Enumeration<String> ()
+            {
+
+                @Override
+                public boolean hasMoreElements()
+                {
+                    return itor.hasNext();
+                }
+
+                @Override
+                public String nextElement()
+                {
+                    return itor.next();
+                }
+
+            };
+        }
+    }
+
+
+
+
+    /* ------------------------------------------------------------ */
+    public int getAttributes()
+    {
+        return _sessionData.getKeys().size();
+    }
+
+
+
+
+    /* ------------------------------------------------------------ */
+    public Set<String> getNames()
+    {
+        return Collections.unmodifiableSet(_sessionData.getKeys());
+    }
+
+
+    /* ------------------------------------------------------------- */
+    /**
+     * @deprecated As of Version 2.2, this method is replaced by
+     *             {@link #getAttributeNames}
+     */
+    @Deprecated
+    @Override
+    public String[] getValueNames() throws IllegalStateException
+    {
+        try (Lock lock = lock())
+        {
+            checkValid();
+            Iterator<String> itor = _sessionData.getKeys().iterator();
+            if (!itor.hasNext())
+                return new String[0];
+            ArrayList<String> names = new ArrayList<String>();
+            while (itor.hasNext())
+                names.add(itor.next());
+            return names.toArray(new String[names.size()]);
+        }
+    }
+
+    /* ------------------------------------------------------------- */
+    /** 
+     * @see javax.servlet.http.HttpSession#setAttribute(java.lang.String, java.lang.Object)
+     */
+    @Override
+    public void setAttribute(String name, Object value)
+    {
+        Object old=null;
+        try (Lock lock = lock())
+        {
+            //if session is not valid, don't accept the set
+            checkValid();
+            old=_sessionData.setAttribute(name,value);
+        }
+        if (value == null && old == null)
+            return; //if same as remove attribute but attribute was already removed, no change
+        callSessionAttributeListeners(name, value, old);
+    }
+    
+    
+    
+    /* ------------------------------------------------------------- */
+    /** 
+     * @see javax.servlet.http.HttpSession#putValue(java.lang.String, java.lang.Object)
+     */
+    @Override
+    public void putValue(String name, Object value)
+    {
+        setAttribute(name,value);
+    }
+    
+    
+    
+    /* ------------------------------------------------------------- */
+    /** 
+     * @see javax.servlet.http.HttpSession#removeAttribute(java.lang.String)
+     */
+    @Override
+    public void removeAttribute(String name)
+    {
+       setAttribute(name, null);
+    }
+    
+    
+    
+    /* ------------------------------------------------------------- */
+    /** 
+     * @see javax.servlet.http.HttpSession#removeValue(java.lang.String)
+     */
+    @Override
+    public void removeValue(String name)
+    {
+       setAttribute(name, null);
+    }
+
+    /* ------------------------------------------------------------ */
+    public void renewId(HttpServletRequest request)
+    {
+        if (_manager == null)
+            throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
+        
+        //TODO
+        //simultaneous calls to renew id on same session - all subsequent calls to renew need to wait 
+        //until first renew finishes - and then should they proceed in order, or does first renew win????
+        //Or are simultaneous interleaved renewals ok, so long as we end up with a consistent result???
+        
+        String id = null;
+        String extendedId = null;
+        try (Lock lock = lock())
+        {
+            checkValid(); //don't renew id on a session that is not valid
+            id = _sessionData.getId(); //grab the values as they are now
+            extendedId = getExtendedId();
+        }
+        
+        _manager._sessionIdManager.renewSessionId(id, extendedId, request); 
+        setIdChanged(true);
+    }
+       
+
+    /* ------------------------------------------------------------- */
+    /** Called by users to invalidate a session, or called by the
+     * access method as a request enters the session if the session
+     * has expired, or called by manager as a result of scavenger
+     * expiring session
+     * 
+     * @see javax.servlet.http.HttpSession#invalidate()
+     */
+    @Override
+    public void invalidate()
+    {
+        if (_manager == null)
+            throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
+
+        boolean result = false;
+
+        try (Lock lock = lock())
+        {
+            switch (_state)
+            {
+                case INVALID:
+                {
+                    throw new IllegalStateException(); //spec does not allow invalidate of already invalid session
+                }
+                case VALID:
+                {
+                    //only first change from valid to invalidating should be actionable
+                    result = true;
+                    _state = State.INVALIDATING;
+                    break;
+                }
+                default:
+                {
+                    LOG.info("Session {} already being invalidated", _sessionData.getId());
+                }
+            }
+        }
+
+        try
+        {
+            //if the session was not already invalid, or in process of being invalidated, do invalidate
+            if (result)
+            {
+                //tell id mgr to remove session from all other contexts
+                ((AbstractSessionIdManager)_manager.getSessionIdManager()).invalidateAll(_sessionData.getId());
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
+    
+    
+    
+    /* ------------------------------------------------------------- */
+    /** Grab the lock on the session
+     * @return
+     */
+    public Lock lock ()
+    {
+        return _lock.lock();
+    }
+
+
+
+
+
+    /* ------------------------------------------------------------- */
+    protected void doInvalidate() throws IllegalStateException
+    {
+        try (Lock lock = lock())
+        {
+            try
+            {
+                if (LOG.isDebugEnabled())
+                    LOG.debug("invalidate {}",_sessionData.getId());
+                if (isValid())
+                    clearAttributes();
+            }
+            finally
+            {
+                // mark as invalid
+                _state = State.INVALID;
+            }
+        }
+    }
+
+    /* ------------------------------------------------------------- */
+    @Override
+    public boolean isNew() throws IllegalStateException
+    {
+        try (Lock lock = lock())
+        {
+            checkValid();
+            return _newSession;
+        }
+    }
+    
+    
+
+    /* ------------------------------------------------------------- */
+    public void setIdChanged(boolean changed)
+    {
+        try (Lock lock = lock())
+        {
+            _idChanged=changed;
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------- */
+    public boolean isIdChanged ()
+    {
+        try (Lock lock = lock())
+        {
+            return _idChanged;
+        }
+    }
+    
+    
+    /* ------------------------------------------------------------- */
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractSessionManager.SessionIf#getSession()
+     */
+    @Override
+    public Session getSession()
+    {
+        // TODO why is this used
+        return this;
+    }
+  
+    /* ------------------------------------------------------------- */
+    protected SessionData getSessionData()
+    {
+        return _sessionData;
+    }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java
new file mode 100644
index 0000000..3f49300
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionContext.java
@@ -0,0 +1,134 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.handler.ContextHandler.Context;
+
+/**
+ * SessionContext
+ *
+ * The worker name which identifies this server instance, and the particular
+ * Context.
+ * 
+ * A SessionManager is 1:1 with a SessionContext.
+ */
+public class SessionContext
+{
+    public final static String NULL_VHOST = "0.0.0.0";
+    private ContextHandler.Context _context;
+    private String _workerName;
+    private String _canonicalContextPath;
+    private String _vhost;
+    
+    
+    public String getWorkerName()
+    {
+        return _workerName;
+    }
+
+
+    public SessionContext (String workerName, ContextHandler.Context context)
+    {
+        _workerName = workerName;
+        _context = context;
+        _canonicalContextPath = canonicalizeContextPath(_context);
+        _vhost = canonicalizeVHost(_context);
+    }
+    
+    
+    public Context getContext ()
+    {
+        return _context;
+    }
+    
+    public String getCanonicalContextPath()
+    {
+        return _canonicalContextPath;
+    }
+    
+    public String getVhost()
+    {
+        return _vhost;
+    }
+    
+    public String toString ()
+    {
+        return _workerName+"_"+_canonicalContextPath +"_"+_vhost;
+    }
+    
+    
+    /**
+     * Run a runnable in the context (with context classloader set) if
+     * there is one, otherwise just run it.
+     * @param r
+     */
+    public void run (Runnable r)
+    {
+        if (_context != null)
+            _context.getContextHandler().handle(r);
+        else
+            r.run();
+    }
+    
+    private String canonicalizeContextPath (Context context)
+    {
+        if (context == null)
+            return "";
+        return canonicalize (context.getContextPath());
+    }
+    
+    
+    /**
+     * Get the first virtual host for the context.
+     *
+     * Used to help identify the exact session/contextPath.
+     *
+     * @return 0.0.0.0 if no virtual host is defined
+     */
+    private String canonicalizeVHost (Context context)
+    {
+        String vhost = NULL_VHOST;
+
+        if (context==null)
+            return vhost;
+
+        String [] vhosts = context.getContextHandler().getVirtualHosts();
+        if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
+            return vhost;
+
+        return vhosts[0];
+    }
+    
+    /**
+     * Make an acceptable name from a context path.
+     *
+     * @param path
+     * @return
+     */
+    private String canonicalize (String path)
+    {
+        if (path==null)
+            return "";
+
+        return path.replace('/', '_').replace('.','_').replace('\\','_');
+    }
+    
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java
new file mode 100644
index 0000000..1cebc42
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java
@@ -0,0 +1,294 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * SessionData
+ *
+ * The data associated with a session. A Session object has a 1:1 relationship
+ * with a SessionData object. The behaviour of sessions is implemented in the
+ * Session object (eg calling listeners, keeping timers etc). A Session's
+ * associated SessionData is the object which can be persisted, serialized etc.
+ */
+public class SessionData implements Serializable
+{
+
+   
+    private static final long serialVersionUID = 1L;
+
+    protected String _id;
+
+    protected String _contextPath;
+    protected String _vhost;
+ 
+    
+    protected String _lastNode;
+    protected long _expiry;
+
+    protected long _created;
+    protected long _cookieSet;
+    protected long _accessed;         // the time of the last access
+    protected long _lastAccessed;     // the time of the last access excluding this one
+   // protected boolean _invalid;
+    protected long _maxInactiveMs;
+    protected Map<String,Object> _attributes = new ConcurrentHashMap<String, Object>();
+    protected boolean _dirty;
+    protected long _lastSaved; //time in msec since last save
+    
+
+    /**
+     * @param id
+     * @param cpath
+     * @param vhost
+     * @param created
+     * @param accessed
+     * @param lastAccessed
+     * @param maxInactiveMs
+     */
+    public SessionData (String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs)
+    {
+        _id = id;
+        setContextPath(cpath);
+        setVhost(vhost);
+        _created = created;
+        _accessed = accessed;
+        _lastAccessed = lastAccessed;
+        _maxInactiveMs = maxInactiveMs;
+    }
+    
+
+    public long getLastSaved()
+    {
+        return _lastSaved;
+    }
+
+
+
+    public void setLastSaved(long lastSaved)
+    {
+        _lastSaved = lastSaved;
+    }
+
+
+    public boolean isDirty()
+    {
+        return _dirty;
+    }
+
+    public void setDirty(boolean dirty)
+    {
+        _dirty = dirty;
+    }
+    
+    public Object getAttribute (String name)
+    {
+        return _attributes.get(name);
+    }
+
+    public Set<String> getKeys()
+    {
+        return _attributes.keySet();
+    }
+    
+    public Object setAttribute (String name, Object value)
+    {
+        Object old = (value==null?_attributes.remove(name):_attributes.put(name,value));
+        if (value == null && old == null)
+            return old; //if same as remove attribute but attribute was already removed, no change
+        
+        setDirty (name);
+       return old;
+    }
+    
+    
+    public void setDirty (String name)
+    {
+        setDirty (true);
+    }
+    
+    
+    
+    public void putAllAttributes (Map<String,Object> attributes)
+    {
+        _attributes.putAll(attributes);
+    }
+    
+    public Map<String,Object> getAllAttributes()
+    {
+        return Collections.unmodifiableMap(_attributes);
+    }
+    
+    public String getId()
+    {
+        return _id;
+    }
+
+    public void setId(String id)
+    {
+        _id = id;
+    }
+
+    public String getContextPath()
+    {
+        return _contextPath;
+    }
+
+    public void setContextPath(String contextPath)
+    {
+        _contextPath = contextPath;
+    }
+
+    public String getVhost()
+    {
+        return _vhost;
+    }
+
+    public void setVhost(String vhost)
+    {
+        _vhost = vhost;
+    }
+
+    public String getLastNode()
+    {
+        return _lastNode;
+    }
+
+    public void setLastNode(String lastNode)
+    {
+        _lastNode = lastNode;
+    }
+
+    public long getExpiry()
+    {
+        return _expiry;
+    }
+
+    public void setExpiry(long expiry)
+    {
+        _expiry = expiry;
+    }
+
+    public long getCreated()
+    {
+        return _created;
+    }
+
+    public void setCreated(long created)
+    {
+        _created = created;
+    }
+
+    public long getCookieSet()
+    {
+        return _cookieSet;
+    }
+
+    public void setCookieSet(long cookieSet)
+    {
+        _cookieSet = cookieSet;
+    }
+
+    public long getAccessed()
+    {
+        return _accessed;
+    }
+
+    public void setAccessed(long accessed)
+    {
+        _accessed = accessed;
+    }
+
+    public long getLastAccessed()
+    {
+        return _lastAccessed;
+    }
+
+    public void setLastAccessed(long lastAccessed)
+    {
+        _lastAccessed = lastAccessed;
+    }
+
+   /* public boolean isInvalid()
+    {
+        return _invalid;
+    }
+*/
+ 
+
+    public long getMaxInactiveMs()
+    {
+        return _maxInactiveMs;
+    }
+
+    public void setMaxInactiveMs(long maxInactive)
+    {
+        _maxInactiveMs = maxInactive;
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException
+    {  
+        out.writeUTF(_id); //session id
+        out.writeUTF(_contextPath); //context path
+        out.writeUTF(_vhost); //first vhost
+
+        out.writeLong(_accessed);//accessTime
+        out.writeLong(_lastAccessed); //lastAccessTime
+        out.writeLong(_created); //time created
+        out.writeLong(_cookieSet);//time cookie was set
+        out.writeUTF(_lastNode); //name of last node managing
+  
+        out.writeLong(_expiry); 
+        out.writeLong(_maxInactiveMs);
+        out.writeObject(_attributes);
+    }
+    
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
+    {
+        _id = in.readUTF();
+        _contextPath = in.readUTF();
+        _vhost = in.readUTF();
+        
+        _accessed = in.readLong();//accessTime
+        _lastAccessed = in.readLong(); //lastAccessTime
+        _created = in.readLong(); //time created
+        _cookieSet = in.readLong();//time cookie was set
+        _lastNode = in.readUTF(); //last managing node
+        _expiry = in.readLong(); 
+        _maxInactiveMs = in.readLong();
+        _attributes = (ConcurrentHashMap<String,Object>)in.readObject();
+    }
+    
+    
+    public boolean isExpiredAt (long time)
+    {
+        if (getExpiry() <= 0)
+            return false; //never expires
+        
+        return (getExpiry() < time);
+    }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java
new file mode 100644
index 0000000..404573a
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java
@@ -0,0 +1,103 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.Set;
+
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/**
+ * SessionDataStore
+ *
+ * A store for the data contained in a Session object. The store
+ * would usually be persistent.
+ */
+public interface SessionDataStore extends LifeCycle
+{
+    /**
+     * Initialize this session data store for the
+     * given context. A SessionDataStore can only 
+     * be used by one context(/session manager).
+     * 
+     * @param context
+     */
+    void initialize(SessionContext context);
+    
+    
+    
+    /**
+     * Read in session data from storage
+     * @param id
+     * @return
+     * @throws Exception
+     */
+    public SessionData load (String id) throws Exception;
+    
+    
+    /**
+     * Create a new SessionData 
+     * @return
+     */
+    public SessionData newSessionData (String id, long created, long accessed, long lastAccessed, long maxInactiveMs);
+    
+    
+    
+    
+    /**
+     * Write out session data to storage
+     * @param id
+     * @param data
+     * @throws Exception
+     */
+    public void store (String id, SessionData data) throws Exception;
+    
+    
+    
+    /**
+     * Delete session data from storage
+     * @param id
+     * @return
+     * @throws Exception
+     */
+    public boolean delete (String id) throws Exception;
+    
+    
+    
+   
+    /**
+     * Called periodically, this method should search the data store
+     * for sessions that have been expired for a 'reasonable' amount 
+     * of time. 
+     * @param candidates if provided, these are keys of sessions that
+     * the SessionStore thinks has expired and should be verified by the
+     * SessionDataStore
+     * @return
+     */
+    public Set<String> getExpired (Set<String> candidates);
+    
+    
+    
+    /**
+     * True if this type of datastore will passivate session objects
+     * @return
+     */
+    public boolean isPassivating ();
+    
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
index 629388f..9e51d91 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java
@@ -243,6 +243,7 @@
         if (requested_session_id != null && sessionManager != null)
         {
             HttpSession session = sessionManager.getHttpSession(requested_session_id);
+            
             if (session != null && sessionManager.isValid(session))
                 baseRequest.setSession(session);
             return;
@@ -273,7 +274,6 @@
                         if (requested_session_id != null)
                         {
                             session = sessionManager.getHttpSession(requested_session_id);
-
                             if (session != null && sessionManager.isValid(session))
                             {
                                 break;
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java
similarity index 77%
rename from jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
rename to jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java
index a833ae7..3721c76 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java
@@ -16,6 +16,7 @@
 //  ========================================================================
 //
 
+
 package org.eclipse.jetty.server.session;
 
 import static java.lang.Math.round;
@@ -43,29 +44,25 @@
 import org.eclipse.jetty.http.HttpCookie;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.SessionIdManager;
-import org.eclipse.jetty.server.SessionManager;
 import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.StringUtil;
 import org.eclipse.jetty.util.annotation.ManagedAttribute;
-import org.eclipse.jetty.util.annotation.ManagedObject;
 import org.eclipse.jetty.util.annotation.ManagedOperation;
 import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 import org.eclipse.jetty.util.statistic.CounterStatistic;
 import org.eclipse.jetty.util.statistic.SampleStatistic;
 
 /**
- * An Abstract implementation of SessionManager.
- * <p>
- * The partial implementation of SessionManager interface provides the majority of the handling required to implement a
- * SessionManager. Concrete implementations of SessionManager based on AbstractSessionManager need only implement the
- * newSession method to return a specialized version of the Session inner class that provides an attribute Map.
+ * SessionManager
+ *
+ *
  */
-@SuppressWarnings("deprecation")
-@ManagedObject("Abstract Session Manager")
-public abstract class AbstractSessionManager extends ContainerLifeCycle implements SessionManager
+public class SessionManager extends ContainerLifeCycle implements org.eclipse.jetty.server.SessionManager
 {
-    final static Logger __log = SessionHandler.LOG;
-
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+            
     public Set<SessionTrackingMode> __defaultSessionTrackingModes =
         Collections.unmodifiableSet(
             new HashSet<SessionTrackingMode>(
@@ -92,7 +89,7 @@
         }
     };
 
-    private boolean _usingCookies=true;
+   
 
     /* ------------------------------------------------------------ */
     // Setting of max inactive interval for new sessions
@@ -110,6 +107,7 @@
 
     protected ClassLoader _loader;
     protected ContextHandler.Context _context;
+    protected SessionContext _sessionContext;
     protected String _sessionCookie=__DefaultSessionCookie;
     protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName;
     protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"=";
@@ -120,17 +118,19 @@
     protected boolean _nodeIdInSessionId;
     protected boolean _checkingRemoteSessionIdEncoding;
     protected String _sessionComment;
-
+    protected SessionStore _sessionStore;
+    protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
+    protected final CounterStatistic _sessionsCreatedStats = new CounterStatistic();
     public Set<SessionTrackingMode> _sessionTrackingModes;
 
     private boolean _usingURLs;
-
-    protected final CounterStatistic _sessionsStats = new CounterStatistic();
-    protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
+    private boolean _usingCookies=true;
 
 
+    
+    
     /* ------------------------------------------------------------ */
-    public AbstractSessionManager()
+    public SessionManager()
     {
         setSessionTrackingModes(__defaultSessionTrackingModes);
     }
@@ -165,7 +165,7 @@
     {
         long now=System.currentTimeMillis();
 
-        AbstractSession s = ((SessionIf)session).getSession();
+        Session s = ((SessionIf)session).getSession();
 
        if (s.access(now))
        {
@@ -213,14 +213,27 @@
     @Override
     public void complete(HttpSession session)
     {
-        AbstractSession s = ((SessionIf)session).getSession();
+        Session s = ((SessionIf)session).getSession();
         s.complete();
+        try
+        {
+            if (s.isValid())
+                _sessionStore.put(s.getId(), s);
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
     }
 
     /* ------------------------------------------------------------ */
     @Override
     public void doStart() throws Exception
     {
+        if (_sessionStore == null)
+            throw new IllegalStateException("No session store configured");
+        
+        
         _context=ContextHandler.getCurrentContext();
         _loader=Thread.currentThread().getContextClassLoader();
 
@@ -240,7 +253,7 @@
                     try
                     {
                         Thread.currentThread().setContextClassLoader(serverLoader);
-                        _sessionIdManager=new HashSessionIdManager();
+                        _sessionIdManager=new HashSessionIdManager(server);
                         server.setSessionIdManager(_sessionIdManager);
                         server.manage(_sessionIdManager);
                         _sessionIdManager.start();
@@ -260,35 +273,44 @@
         // Look for a session cookie name
         if (_context!=null)
         {
-            String tmp=_context.getInitParameter(SessionManager.__SessionCookieProperty);
+            String tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionCookieProperty);
             if (tmp!=null)
                 _sessionCookie=tmp;
 
-            tmp=_context.getInitParameter(SessionManager.__SessionIdPathParameterNameProperty);
+            tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionIdPathParameterNameProperty);
             if (tmp!=null)
                 setSessionIdPathParameterName(tmp);
 
             // set up the max session cookie age if it isn't already
             if (_maxCookieAge==-1)
             {
-                tmp=_context.getInitParameter(SessionManager.__MaxAgeProperty);
+                tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__MaxAgeProperty);
                 if (tmp!=null)
                     _maxCookieAge=Integer.parseInt(tmp.trim());
             }
 
             // set up the session domain if it isn't already
             if (_sessionDomain==null)
-                _sessionDomain=_context.getInitParameter(SessionManager.__SessionDomainProperty);
+                _sessionDomain=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionDomainProperty);
 
             // set up the sessionPath if it isn't already
             if (_sessionPath==null)
-                _sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty);
+                _sessionPath=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__SessionPathProperty);
 
-            tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding);
+            tmp=_context.getInitParameter(org.eclipse.jetty.server.SessionManager.__CheckRemoteSessionEncoding);
             if (tmp!=null)
                 _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
         }
+       
+        _sessionContext = new SessionContext(_sessionIdManager.getWorkerName(), _context);
 
+       if (_sessionStore instanceof AbstractSessionStore)
+           ((AbstractSessionStore)_sessionStore).setSessionManager(this);
+       
+       
+       _sessionStore.initialize(_sessionContext);
+       _sessionStore.start();
+       
         super.doStart();
     }
 
@@ -296,10 +318,9 @@
     @Override
     public void doStop() throws Exception
     {
-        super.doStop();
-
         shutdownSessions();
-
+        _sessionStore.stop();
+        super.doStop();
         _loader=null;
     }
 
@@ -316,12 +337,12 @@
 
     /* ------------------------------------------------------------ */
     @Override
-    public HttpSession getHttpSession(String nodeId)
+    public HttpSession getHttpSession(String extendedId)
     {
-        String cluster_id = getSessionIdManager().getClusterId(nodeId);
+        String id = getSessionIdManager().getId(extendedId);
 
-        AbstractSession session = getSession(cluster_id);
-        if (session!=null && !session.getNodeId().equals(nodeId))
+        Session session = getSession(id);
+        if (session!=null && !session.getExtendedId().equals(extendedId))
             session.setIdChanged(true);
         return session;
     }
@@ -343,31 +364,13 @@
      * @return seconds
      */
     @Override
-    @ManagedAttribute("defailt maximum time a session may be idle for (in s)")
+    @ManagedAttribute("default maximum time a session may be idle for (in s)")
     public int getMaxInactiveInterval()
     {
         return _dftMaxIdleSecs;
     }
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return maximum number of sessions
-     */
-    @ManagedAttribute("maximum number of simultaneous sessions")
-    public int getSessionsMax()
-    {
-        return (int)_sessionsStats.getMax();
-    }
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return total number of sessions
-     */
-    @ManagedAttribute("total number of sessions")
-    public int getSessionsTotal()
-    {
-        return (int)_sessionsStats.getTotal();
-    }
 
     /* ------------------------------------------------------------ */
     @ManagedAttribute("time before a session cookie is re-set (in s)")
@@ -451,7 +454,7 @@
         {
             String sessionPath = (_cookieConfig.getPath()==null) ? contextPath : _cookieConfig.getPath();
             sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
-            String id = getNodeId(session);
+            String id = getExtendedId(session);
             HttpCookie cookie = null;
             if (_sessionComment == null)
             {
@@ -499,10 +502,10 @@
     }
 
     /* ------------------------------------------------------------ */
-    @ManagedAttribute("number of currently active sessions")
-    public int getSessions()
+    @ManagedAttribute("number of sessions created by this node")
+    public int getSessionsCreated()
     {
-        return (int)_sessionsStats.getCurrent();
+        return (int) _sessionsCreatedStats.getCurrent();
     }
 
     /* ------------------------------------------------------------ */
@@ -534,24 +537,24 @@
     @Override
     public boolean isValid(HttpSession session)
     {
-        AbstractSession s = ((SessionIf)session).getSession();
+        Session s = ((SessionIf)session).getSession();
         return s.isValid();
     }
 
     /* ------------------------------------------------------------ */
     @Override
-    public String getClusterId(HttpSession session)
+    public String getId(HttpSession session)
     {
-        AbstractSession s = ((SessionIf)session).getSession();
-        return s.getClusterId();
+        Session s = ((SessionIf)session).getSession();
+        return s.getId();
     }
 
     /* ------------------------------------------------------------ */
     @Override
-    public String getNodeId(HttpSession session)
+    public String getExtendedId(HttpSession session)
     {
-        AbstractSession s = ((SessionIf)session).getSession();
-        return s.getNodeId();
+        Session s = ((SessionIf)session).getSession();
+        return s.getExtendedId();
     }
 
     /* ------------------------------------------------------------ */
@@ -561,12 +564,39 @@
     @Override
     public HttpSession newHttpSession(HttpServletRequest request)
     {
-        AbstractSession session=newSession(request);
-        session.setMaxInactiveInterval(_dftMaxIdleSecs);
+        long created=System.currentTimeMillis();
+        String id =_sessionIdManager.newSessionId(request,created);      
+        Session session = _sessionStore.newSession(request, id, created,  (_dftMaxIdleSecs>0?_dftMaxIdleSecs*1000L:-1));
+        session.setExtendedId(_sessionIdManager.getExtendedId(id,request));
+        session.setSessionManager(this);
+        session.setLastNode(_sessionIdManager.getWorkerName());
+        session.getSessionData().setExpiry(_dftMaxIdleSecs <= 0 ? 0 : (created + _dftMaxIdleSecs*1000L));
+
         if (request.isSecure())
-            session.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE);
-        addSession(session,true);
-        return session;
+            session.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
+
+        try
+        {
+            _sessionStore.put(id, session);
+            
+            _sessionsCreatedStats.increment();
+            
+            _sessionIdManager.useId(session);
+            
+            if (_sessionListeners!=null)
+            {
+                HttpSessionEvent event=new HttpSessionEvent(session);
+                for (HttpSessionListener listener : _sessionListeners)
+                    listener.sessionCreated(event);
+            }
+
+            return session;
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+            return null;
+        }      
     }
 
     /* ------------------------------------------------------------ */
@@ -589,7 +619,7 @@
     @ManagedOperation(value="reset statistics", impact="ACTION")
     public void statsReset()
     {
-        _sessionsStats.reset(getSessions());
+        _sessionsCreatedStats.reset();
         _sessionTimeStats.reset();
     }
 
@@ -663,60 +693,70 @@
     }
 
 
-    protected abstract void addSession(AbstractSession session);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Add the session Registers the session with this manager and registers the
-     * session ID with the sessionIDManager;
-     * @param session the session
-     * @param created true if session was created
-     */
-    protected void addSession(AbstractSession session, boolean created)
-    {
-        synchronized (_sessionIdManager)
-        {
-            _sessionIdManager.addSession(session);
-            addSession(session);
-        }
-
-        if (created)
-        {
-            _sessionsStats.increment();
-            if (_sessionListeners!=null)
-            {
-                HttpSessionEvent event=new HttpSessionEvent(session);
-                for (HttpSessionListener listener : _sessionListeners)
-                    listener.sessionCreated(event);
-            }
-        }
-    }
 
     /* ------------------------------------------------------------ */
     /**
      * Get a known existing session
-     * @param idInCluster The session ID in the cluster, stripped of any worker name.
+     * @param id The session ID stripped of any worker name.
      * @return A Session or null if none exists.
      */
-    public abstract AbstractSession getSession(String idInCluster);
+    public Session getSession(String id)
+    {
+        try
+        {
+            Session session =  _sessionStore.get(id, true);
+            if (session != null)
+            {
+                //If the session we got back has expired
+                if (session.isExpiredAt(System.currentTimeMillis()))
+                {
+                    //Tell the id manager that this session id should not be used in case other threads
+                    //try to use the same session id in other contexts
+                    _sessionIdManager.removeId(id);    
+                    //The scavenger thread will pick up this expired session
+                    return null;
+                }
+                
+                session.setExtendedId(_sessionIdManager.getExtendedId(id, null)); //TODO not sure if this is OK?
+                session.setLastNode(_sessionIdManager.getWorkerName());  //TODO write through the change of node?
+            }
+            return session;
+        }
+        catch (UnreadableSessionDataException e)
+        {
+            LOG.warn(e);
+            //Could not retrieve the session with the given id
+            //Tell the session id manager that the session id is not to be used by any other threads/contexts
+            _sessionIdManager.removeId(id);
+            return null;
+        }
+        catch (Exception other)
+        {
+            LOG.warn(other);
+            return null;
+        }
+    }
 
     /**
      * Prepare sessions for session manager shutdown
      * 
      * @throws Exception if unable to shutdown sesssions
      */
-    protected abstract void shutdownSessions() throws Exception;
+    protected void shutdownSessions() throws Exception
+    {
+        _sessionStore.shutdown();
+    }
 
 
     /* ------------------------------------------------------------ */
     /**
-     * Create a new session instance
-     * @param request the request to build the session from
-     * @return the new session
+     * @return
      */
-    protected abstract AbstractSession newSession(HttpServletRequest request);
-
-
+    public SessionStore getSessionStore ()
+    {
+        return _sessionStore;
+    }
+    
     /* ------------------------------------------------------------ */
     /**
      * @return true if the cluster node id (worker id) is returned as part of the session id by {@link HttpSession#getId()}. Default is false.
@@ -735,56 +775,47 @@
         _nodeIdInSessionId=nodeIdInSessionId;
     }
 
-    /* ------------------------------------------------------------ */
-    /** Remove session from manager
-     * @param session The session to remove
-     * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
-     * {@link SessionIdManager#invalidateAll(String)} should be called.
-     */
-    public void removeSession(HttpSession session, boolean invalidate)
-    {
-        AbstractSession s = ((SessionIf)session).getSession();
-        removeSession(s,invalidate);
-    }
 
     /* ------------------------------------------------------------ */
     /** 
      * Remove session from manager
-     * @param session The session to remove
+     * @param id The session to remove
      * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
-     * {@link SessionIdManager#invalidateAll(String)} should be called.
+     * {@link SessionIdManager#expireAll(String)} should be called.
      * @return if the session was removed 
      */
-    public boolean removeSession(AbstractSession session, boolean invalidate)
+    public Session removeSession(String id, boolean invalidate)
     {
-        // Remove session from context and global maps
-        boolean removed = removeSession(session.getClusterId());
-
-        if (removed)
+        try
         {
-            _sessionsStats.decrement();
-            _sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0));
-
-            // Remove session from all context and global id maps
-            _sessionIdManager.removeSession(session);
-            if (invalidate)
-                _sessionIdManager.invalidateAll(session.getClusterId());
-
-            if (invalidate && _sessionListeners!=null)
+            //Remove the Session object from the session store and any backing data store
+            Session session = _sessionStore.delete(id);
+            if (session != null)
             {
-                HttpSessionEvent event=new HttpSessionEvent(session);      
-                for (int i = _sessionListeners.size()-1; i>=0; i--)
+                if (invalidate)
                 {
-                    _sessionListeners.get(i).sessionDestroyed(event);
+                    if (_sessionListeners!=null)
+                    {
+                        HttpSessionEvent event=new HttpSessionEvent(session);      
+                        for (int i = _sessionListeners.size()-1; i>=0; i--)
+                        {
+                            _sessionListeners.get(i).sessionDestroyed(event);
+                        }
+                    }
                 }
             }
-        }
-        
-        return removed;
-    }
 
-    /* ------------------------------------------------------------ */
-    protected abstract boolean removeSession(String idInCluster);
+            return session;
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+            return null;
+        }
+    }
+    
+    
+   
 
     /* ------------------------------------------------------------ */
     /**
@@ -888,30 +919,102 @@
     {
         _checkingRemoteSessionIdEncoding=remote;
     }
+
+
+    /* ------------------------------------------------------------ */
+    /**
+     * Change the session id and tell the HttpSessionIdListeners the id changed.
+     * 
+     */
+    @Override
+    public void renewSessionId(String oldId, String oldExtendedId, String newId, String newExtendedId)
+    {
+        try
+        {
+            Session session = _sessionStore.get(oldId, true);
+            if (session == null)
+            {
+                LOG.warn("Unable to renew id to "+newId+" for non-existant session "+oldId);
+                return;
+            }
+
+            //save session with new id
+            session.getSessionData().setId(newId);
+            session.setExtendedId(newExtendedId);
+            session.getSessionData().setLastSaved(0); //forces an insert
+            session.getSessionData().setDirty(true);  //forces an insert
+            _sessionStore.put(newId, session);
+  
+            //tell session id manager the id is in use
+            _sessionIdManager.useId(session);
+            
+            //remove session with old id
+            _sessionStore.delete(oldId);
+
+            //inform the listeners
+            if (!_sessionIdListeners.isEmpty())
+            {
+                HttpSessionEvent event = new HttpSessionEvent(session);
+                for (HttpSessionIdListener l:_sessionIdListeners)
+                {
+                    l.sessionIdChanged(event, oldId);
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
+    }
     
+   
     
     /* ------------------------------------------------------------ */
     /**
-     * Tell the HttpSessionIdListeners the id changed.
-     * NOTE: this method must be called LAST in subclass overrides, after the session has been updated
-     * with the new id.
-     * @see org.eclipse.jetty.server.SessionManager#renewSessionId(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     * Called either when a session has expired, or the app has
+     * invalidated it.
+     * 
+     * @param id
      */
-    @Override
-    public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
+    public void invalidate (String id)
     {
-        if (!_sessionIdListeners.isEmpty())
+        if (StringUtil.isBlank(id))
+            return;
+
+        try
         {
-            AbstractSession session = getSession(newClusterId);
-            HttpSessionEvent event = new HttpSessionEvent(session);
-            for (HttpSessionIdListener l:_sessionIdListeners)
+            //remove the session and call the destroy listeners
+            Session session = removeSession(id, true);
+
+            if (session != null)
             {
-                l.sessionIdChanged(event, oldClusterId);
+                _sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
+                session.doInvalidate();   
             }
         }
-
+        catch (Exception e)
+        {
+            LOG.warn(e);
+        }
     }
 
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * @return
+     */
+    public Set<String> scavenge ()
+    {
+        //don't attempt to scavenge if we are shutting down
+        if (isStopping() || isStopped())
+            return Collections.emptySet();
+
+        return _sessionStore.getExpired();
+    }
+    
+  
+
+
     /**
      * CookieConfig
      * 
@@ -1028,10 +1131,10 @@
      */
     public interface SessionIf extends HttpSession
     {
-        public AbstractSession getSession();
+        public Session getSession();
     }
 
-    public void doSessionAttributeListeners(AbstractSession session, String name, Object old, Object value)
+    public void doSessionAttributeListeners(Session session, String name, Object old, Object value)
     {
         if (!_sessionAttributeListeners.isEmpty())
         {
@@ -1048,11 +1151,4 @@
             }
         }
     }
-
-    @Override
-    @Deprecated
-    public SessionIdManager getMetaManager()
-    {
-        throw new UnsupportedOperationException();
-    }
 }
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionScavenger.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionScavenger.java
new file mode 100644
index 0000000..21cb4a7
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionScavenger.java
@@ -0,0 +1,243 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.SessionIdManager;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
+import org.eclipse.jetty.util.thread.Scheduler;
+
+/**
+ * SessionScavenger
+ *
+ * There is 1 session scavenger per SessionIdManager
+ *
+ */
+public class SessionScavenger extends AbstractLifeCycle
+{
+    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
+    
+    public static final long DEFAULT_SCAVENGE_MS = 1000L * 60 * 10;
+    protected SessionIdManager _sessionIdManager;
+    protected Scheduler _scheduler;
+    protected Scheduler.Task _task; //scavenge task
+    protected ScavengerRunner _runner;
+    protected boolean _ownScheduler = false;
+    private long _scavengeIntervalMs =  DEFAULT_SCAVENGE_MS;
+    
+    
+    
+    /**
+     * ScavengerRunner
+     *
+     */
+    protected class ScavengerRunner implements Runnable
+    {
+
+        @Override
+        public void run()
+        {
+           try
+           {
+               scavenge();
+           }
+           finally
+           {
+               if (_scheduler != null && _scheduler.isRunning())
+                   _task = _scheduler.schedule(this, _scavengeIntervalMs, TimeUnit.MILLISECONDS);
+           }
+        }
+    }
+    
+    
+    
+    
+    /**
+     * SessionIdManager associated with this scavenger
+     * @param sessionIdManager
+     */
+    public void setSessionIdManager (SessionIdManager sessionIdManager)
+    {
+        _sessionIdManager = sessionIdManager;
+    }
+    
+    
+    /** 
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
+     */
+    @Override
+    protected void doStart() throws Exception
+    {
+        if (_sessionIdManager == null)
+            throw new IllegalStateException ("No SessionIdManager for Scavenger");
+        
+        if (!(_sessionIdManager instanceof AbstractSessionIdManager))
+            throw new IllegalStateException ("SessionIdManager is not an AbstractSessionIdManager");
+
+
+        //try and use a common scheduler, fallback to own
+        _scheduler = ((AbstractSessionIdManager)_sessionIdManager).getServer().getBean(Scheduler.class);
+
+        if (_scheduler == null)
+        {
+            _scheduler = new ScheduledExecutorScheduler();
+            _ownScheduler = true;
+            _scheduler.start();
+        }
+        else if (!_scheduler.isStarted())
+            throw new IllegalStateException("Shared scheduler not started");
+
+        setScavengeIntervalSec(getScavengeIntervalSec());
+        
+        super.doStart();
+    }
+
+    /** 
+     * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
+     */
+    @Override
+    protected void doStop() throws Exception
+    {
+        synchronized(this)
+        {
+            if (_task != null)
+                _task.cancel();
+            _task=null;
+            if (_ownScheduler && _scheduler !=null)
+                _scheduler.stop();
+            _scheduler = null;
+            _runner = null;
+        }
+        super.doStop();
+    }
+    
+    
+    /**
+     * Set the period between scavenge cycles
+     * @param sec
+     */
+    public void setScavengeIntervalSec (long sec)
+    {
+        if (sec<=0)
+            sec=60;
+
+        long old_period=_scavengeIntervalMs;
+        long period=sec*1000L;
+
+        _scavengeIntervalMs=period;
+
+        //add a bit of variability into the scavenge time so that not all
+        //nodes with the same scavenge interval sync up
+        long tenPercent = _scavengeIntervalMs/10;
+        if ((System.currentTimeMillis()%2) == 0)
+            _scavengeIntervalMs += tenPercent;
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms");
+        
+        synchronized (this)
+        {
+            if (_scheduler != null && (period!=old_period || _task==null))
+            {
+                if (_task!=null)
+                    _task.cancel();
+                if (_runner == null)
+                    _runner = new ScavengerRunner();
+                _task = _scheduler.schedule(_runner,_scavengeIntervalMs,TimeUnit.MILLISECONDS);
+            }
+        }
+    }
+
+    /**
+     * Get the period between scavenge cycles.
+     * 
+     * @return
+     */
+    public long getScavengeIntervalSec ()
+    {
+        return _scavengeIntervalMs/1000;
+    }
+    
+    
+    
+    /**
+     * Perform a scavenge cycle:
+     *   ask all SessionManagers to find sessions they think have expired and then make
+     *   sure that a session sharing the same id is expired on all contexts
+     */
+    public void scavenge ()
+    {
+        //don't attempt to scavenge if we are shutting down
+        if (isStopping() || isStopped())
+            return;
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("Scavenging sessions");
+        
+        //find the session managers
+        Handler[] contexts = ((AbstractSessionIdManager)_sessionIdManager).getServer().getChildHandlersByClass(ContextHandler.class);
+        for (int i=0; contexts!=null && i<contexts.length; i++)
+        {
+            SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+            if (sessionHandler != null)
+            {
+                SessionManager manager = (SessionManager) sessionHandler.getSessionManager();
+                if (manager != null)
+                {
+                    //call scavenge on each manager to find keys for sessions that have expired
+                    Set<String> expiredKeys = manager.scavenge();
+                    
+                    //for each expired session, tell the session id manager to invalidate its key on all contexts
+                    for (String key:expiredKeys)
+                    {
+                        try
+                        {
+                            ((AbstractSessionIdManager)_sessionIdManager).expireAll(key);
+                        }
+                        catch (Exception e)
+                        {
+                            LOG.warn(e);
+                        }
+                    }
+
+                }
+            }
+        }
+
+    }
+
+
+    /** 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString()
+    {
+        return super.toString()+"[interval="+_scavengeIntervalMs+", ownscheduler="+_ownScheduler+"]";
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java
new file mode 100644
index 0000000..a725192
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java
@@ -0,0 +1,47 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/**
+ * SessionStore
+ *
+ * A store of Session objects.  This store of Session objects can be backed by
+ * a SessionDataStore to persist/distribute the data contained in the Session objects.
+ * 
+ * This store of Session objects ensures that all threads within the same context on
+ * the same node with the same session id will share exactly the same Session object.
+ */
+public interface SessionStore extends LifeCycle
+{
+    void initialize(SessionContext context);
+    Session newSession (HttpServletRequest request, String id,  long time, long maxInactiveMs);
+    Session get(String id, boolean staleCheck) throws Exception;
+    void put(String id, Session session) throws Exception;
+    boolean exists (String id) throws Exception;
+    Session delete (String id) throws Exception;
+    void shutdown ();
+    Set<String> getExpired ();
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/StalePeriodStrategy.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/StalePeriodStrategy.java
new file mode 100644
index 0000000..fa30e1f
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/StalePeriodStrategy.java
@@ -0,0 +1,80 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * StalePeriodStrategy
+ *
+ * A session is regarded as being stale if it has been 
+ * x seconds since it was last read from the cluster.
+ */
+public class StalePeriodStrategy implements StalenessStrategy
+{
+    protected long _staleMs = 0;
+
+    /** 
+     * @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
+     */
+    @Override
+    public boolean isStale (Session session)
+    {
+        if (session == null)
+            return false;
+        
+        //never persisted, must be fresh session
+        if (session.getSessionData().getLastSaved() == 0)
+            return false;
+        
+        if (_staleMs <= 0)
+        {
+            //TODO always stale, never stale??
+            return false;
+        }
+        else
+        {
+           // return (session.getSessionData().getAccessed() - session.getSessionData().getLastSaved() >= _staleMs);
+            return (System.currentTimeMillis() - session.getSessionData().getLastSaved() >= _staleMs);
+        }
+            
+    }
+    
+    
+    /**
+     * @return
+     */
+    public long getStaleSec ()
+    {
+        return (_staleMs<=0?0L:_staleMs/1000L);
+    }
+    
+    /**
+     * The amount of time in seconds that a session can be held
+     * in memory without being refreshed from the cluster.
+     * @param sec
+     */
+    public void setStaleSec (long sec)
+    {
+        if (sec == 0)
+            _staleMs = 0L;
+        else
+            _staleMs = sec * 1000L;
+    }
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/StalenessStrategy.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/StalenessStrategy.java
new file mode 100644
index 0000000..e23c7d8
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/StalenessStrategy.java
@@ -0,0 +1,30 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * StalenessStrategy
+ *
+ *
+ */
+public interface StalenessStrategy
+{
+    boolean isStale (Session session);
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java
new file mode 100644
index 0000000..8c6a3be
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnreadableSessionDataException.java
@@ -0,0 +1,59 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * UnreadableSessionData
+ *
+ *
+ */
+public class UnreadableSessionDataException extends Exception
+{
+    private String _id;
+    private SessionContext _sessionContext;
+    
+    
+    public String getId()
+    {
+        return _id;
+    }
+    
+    public SessionContext getSessionContext()
+    {
+        return _sessionContext;
+    }
+
+
+    public UnreadableSessionDataException (String id, SessionContext contextId, Throwable t)
+    {
+        super ("Unreadable session "+id+" for "+contextId, t);
+        _sessionContext = contextId;
+        _id = id;
+    }
+    
+    public UnreadableSessionDataException (String id, SessionContext contextId, boolean loadAttemptsExhausted)
+    {
+        super("Unreadable session "+id+" for "+contextId+(loadAttemptsExhausted?" max load attempts":""));
+        _sessionContext = contextId;
+        _id = id;
+    }
+    
+
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java
new file mode 100644
index 0000000..b222d6a
--- /dev/null
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/UnwriteableSessionDataException.java
@@ -0,0 +1,49 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+
+package org.eclipse.jetty.server.session;
+
+/**
+ * UnwriteableSessionDataException
+ *
+ *
+ */
+public class UnwriteableSessionDataException extends Exception
+{
+    private String _id;
+    private SessionContext _sessionContext;
+    
+    
+    
+    public UnwriteableSessionDataException (String id, SessionContext contextId, Throwable t)
+    {
+        super ("Unwriteable session "+id+" for "+contextId, t);
+       _id = id;
+    }
+    
+    public String getId()
+    {
+        return _id;
+    }
+    
+    public SessionContext getSessionContext()
+    {
+        return _sessionContext;
+    }
+}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/jmx/SessionManagerMBean.java
similarity index 84%
rename from jetty-server/src/main/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java
rename to jetty-server/src/main/java/org/eclipse/jetty/server/session/jmx/SessionManagerMBean.java
index 377ddc3..b3c2e9f 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/jmx/AbstractSessionManagerMBean.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/jmx/SessionManagerMBean.java
@@ -21,12 +21,12 @@
 import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
 import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.server.handler.jmx.AbstractHandlerMBean;
-import org.eclipse.jetty.server.session.AbstractSessionManager;
+import org.eclipse.jetty.server.session.SessionManager;
 import org.eclipse.jetty.server.session.SessionHandler;
 
-public class AbstractSessionManagerMBean extends AbstractHandlerMBean
+public class SessionManagerMBean extends AbstractHandlerMBean
 {
-    public AbstractSessionManagerMBean(Object managedObject)
+    public SessionManagerMBean(Object managedObject)
     {
         super(managedObject);
     }
@@ -34,9 +34,9 @@
     /* ------------------------------------------------------------ */
     public String getObjectContextBasis()
     {
-        if (_managed != null && _managed instanceof AbstractSessionManager)
+        if (_managed != null && _managed instanceof SessionManager)
         {
-            AbstractSessionManager manager = (AbstractSessionManager)_managed;
+            SessionManager manager = (SessionManager)_managed;
             
             String basis = null;
             SessionHandler handler = manager.getSessionHandler();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
index f6f6781..7f8bce9 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java
@@ -55,7 +55,8 @@
 import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.server.session.HashSessionIdManager;
 import org.eclipse.jetty.server.session.HashSessionManager;
-import org.eclipse.jetty.server.session.HashedSession;
+import org.eclipse.jetty.server.session.Session;
+import org.eclipse.jetty.server.session.SessionData;
 import org.eclipse.jetty.util.Callback;
 import org.eclipse.jetty.util.thread.Scheduler;
 import org.eclipse.jetty.util.thread.TimerScheduler;
@@ -465,9 +466,11 @@
         request.setRequestedSessionId("12345");
         request.setRequestedSessionIdFromCookie(false);
         HashSessionManager manager = new HashSessionManager();
-        manager.setSessionIdManager(new HashSessionIdManager());
+        manager.setSessionIdManager(new HashSessionIdManager(_server));
         request.setSessionManager(manager);
-        request.setSession(new TestSession(manager, "12345"));
+        TestSession tsession = new TestSession(manager, "12345");
+        tsession.setExtendedId(manager.getSessionIdManager().getExtendedId("12345", null));
+        request.setSession(tsession);
 
         manager.setCheckingRemoteSessionIdEncoding(false);
 
@@ -540,7 +543,7 @@
                     request.setRequestedSessionId("12345");
                     request.setRequestedSessionIdFromCookie(i>2);
                     HashSessionManager manager = new HashSessionManager();
-                    manager.setSessionIdManager(new HashSessionIdManager());
+                    manager.setSessionIdManager(new HashSessionIdManager(_server));
                     request.setSessionManager(manager);
                     request.setSession(new TestSession(manager, "12345"));
                     manager.setCheckingRemoteSessionIdEncoding(false);
@@ -836,11 +839,12 @@
         return new Response(_channel, _channel.getResponse().getHttpOutput());
     }
 
-    private static class TestSession extends HashedSession
+    private static class TestSession extends Session
     {
         protected TestSession(HashSessionManager hashSessionManager, String id)
         {
-            super(hashSessionManager, 0L, 0L, id);
+            super(new SessionData(id, "", "0.0.0.0", 0, 0, 0, 300));
+            setSessionManager(hashSessionManager);
         }
     }
 }
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java
new file mode 100644
index 0000000..b7bf922
--- /dev/null
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java
@@ -0,0 +1,173 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import java.io.File;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.toolchain.test.FS;
+import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.util.IO;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.StdErrLog;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class FileSessionManagerTest
+{
+    private static StdErrLog _log;
+    private static boolean _stacks;
+  
+    
+    @BeforeClass
+    public static void beforeClass ()
+    {
+        _log = ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.session"));
+        _stacks = _log.isHideStacks();
+        _log.setHideStacks(true);
+    }
+    
+    @AfterClass
+    public static void afterClass()
+    {
+        _log.setHideStacks(_stacks);
+    }
+    
+    
+    
+    @Test
+    public void testDangerousSessionIdRemoval() throws Exception
+    {
+        Server server = new Server();
+        SessionHandler handler = new SessionHandler();
+        handler.setServer(server);
+        final HashSessionIdManager idmgr = new HashSessionIdManager(server);
+        idmgr.setServer(server);
+        server.setSessionIdManager(idmgr);
+        
+        final FileSessionManager manager = new FileSessionManager();
+        manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
+        //manager.setLazyLoad(true);
+        File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
+        testDir.mkdirs();
+        manager.getSessionDataStore().setStoreDir(testDir);
+        manager.setSessionIdManager(idmgr);
+        handler.setSessionManager(manager);
+        manager.start();
+        
+        String expectedFilename = "../../_0.0.0.0_dangerFile";
+        
+        MavenTestingUtils.getTargetFile(expectedFilename).createNewFile();
+        
+        Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile(expectedFilename).exists());
+
+        manager.getSession("../../_0.0.0.0_dangerFile");
+        
+        Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile(expectedFilename).exists());
+
+    }
+
+    @Test
+    public void testValidSessionIdRemoval() throws Exception
+    {      
+        Server server = new Server();
+        SessionHandler handler = new SessionHandler();
+        handler.setServer(server);
+        final HashSessionIdManager idmgr = new HashSessionIdManager(server);
+        idmgr.setServer(server);
+        server.setSessionIdManager(idmgr);
+        final FileSessionManager manager = new FileSessionManager();
+        manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
+        manager.setSessionIdManager(idmgr);
+        handler.setSessionManager(manager);
+        File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
+        FS.ensureEmpty(testDir);
+
+        manager.getSessionDataStore().setStoreDir(testDir);
+        manager.start();
+
+        String expectedFilename = "_0.0.0.0_validFile123";
+        
+        Assert.assertTrue(new File(testDir, expectedFilename).createNewFile());
+
+        Assert.assertTrue("File should exist!", new File(testDir, expectedFilename).exists());
+
+        manager.getSession("validFile123");
+
+        Assert.assertTrue("File shouldn't exist!", !new File(testDir,expectedFilename).exists());
+    }
+
+    @Test
+    public void testHashSession() throws Exception
+    {
+        File testDir = MavenTestingUtils.getTargetTestingDir("saved");
+        IO.delete(testDir);
+        testDir.mkdirs();
+
+        Server server = new Server();
+        SessionHandler handler = new SessionHandler();
+        handler.setServer(server);
+        FileSessionManager manager = new FileSessionManager();
+        manager.getSessionDataStore().setStoreDir(testDir);
+        manager.setMaxInactiveInterval(5);
+        Assert.assertTrue(testDir.exists());
+        Assert.assertTrue(testDir.canWrite());
+        handler.setSessionManager(manager);
+        
+        AbstractSessionIdManager idManager = new HashSessionIdManager(server);
+        idManager.setServer(server);
+        idManager.setWorkerName("foo");
+        manager.setSessionIdManager(idManager);
+        server.setSessionIdManager(idManager);
+        
+        server.start();
+        manager.start();
+        
+        Session session = (Session)manager.newHttpSession(new Request(null, null));
+        String sessionId = session.getId();
+        
+        session.setAttribute("one", new Integer(1));
+        session.setAttribute("two", new Integer(2));    
+        
+        //stop will persist sessions
+        manager.setMaxInactiveInterval(30); // change max inactive interval for *new* sessions
+        manager.stop();
+        
+        String expectedFilename = "_0.0.0.0_"+session.getId();
+        Assert.assertTrue("File should exist!", new File(testDir, expectedFilename).exists());
+        
+        
+        manager.start();
+        
+        //restore session
+        Session restoredSession = (Session)manager.getSession(sessionId);
+        Assert.assertNotNull(restoredSession);
+        
+        Object o = restoredSession.getAttribute("one");
+        Assert.assertNotNull(o);
+        
+        Assert.assertEquals(1, ((Integer)o).intValue());
+        Assert.assertEquals(5, restoredSession.getMaxInactiveInterval());     
+        
+        server.stop();
+    }
+}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
deleted file mode 100644
index b7a5eed..0000000
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.server.session;
-
-import java.io.File;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.toolchain.test.FS;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.eclipse.jetty.util.IO;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class HashSessionManagerTest
-{
-    @Test
-    public void testDangerousSessionIdRemoval() throws Exception
-    {
-        final HashSessionManager manager = new HashSessionManager();
-        manager.setDeleteUnrestorableSessions(true);
-        manager.setLazyLoad(true);
-        File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
-        testDir.mkdirs();
-        manager.setStoreDirectory(testDir);
-
-        MavenTestingUtils.getTargetFile("dangerFile.session").createNewFile();
-        
-        Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile("dangerFile.session").exists());
-
-        manager.getSession("../../dangerFile.session");
-        
-        Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile("dangerFile.session").exists());
-
-    }
-    
-   @Test
-    public void testValidSessionIdRemoval() throws Exception
-    {
-        final HashSessionManager manager = new HashSessionManager();
-        manager.setDeleteUnrestorableSessions(true);
-        manager.setLazyLoad(true);
-        File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
-        FS.ensureEmpty(testDir);
-        
-        manager.setStoreDirectory(testDir);
-
-        Assert.assertTrue(new File(testDir, "validFile.session").createNewFile());
-        
-        Assert.assertTrue("File should exist!", new File(testDir, "validFile.session").exists());
-       
-        manager.getSession("validFile.session");
-
-        Assert.assertTrue("File shouldn't exist!", !new File(testDir,"validFile.session").exists());
-    }
-    
-    @Test
-    public void testHashSession() throws Exception
-    {
-        File testDir = MavenTestingUtils.getTargetTestingDir("saved");
-        IO.delete(testDir);
-        testDir.mkdirs();
-        
-        Server server = new Server();
-        SessionHandler handler = new SessionHandler();
-        handler.setServer(server);
-        HashSessionManager manager = new HashSessionManager();
-        manager.setStoreDirectory(testDir);
-        manager.setMaxInactiveInterval(5);
-        Assert.assertTrue(testDir.exists());
-        Assert.assertTrue(testDir.canWrite());
-        handler.setSessionManager(manager);
-        
-        AbstractSessionIdManager idManager = new HashSessionIdManager();
-        idManager.setWorkerName("foo");
-        manager.setSessionIdManager(idManager);
-        server.setSessionIdManager(idManager);
-        
-        server.start();
-        manager.start();
-        
-        HashedSession session = (HashedSession)manager.newHttpSession(new Request(null, null));
-        String sessionId = session.getId();
-        
-        session.setAttribute("one", new Integer(1));
-        session.setAttribute("two", new Integer(2));    
-        
-        //stop will persist sessions
-        manager.setMaxInactiveInterval(30); // change max inactive interval for *new* sessions
-        manager.stop();
-        
-        Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());
-        
-        //start will restore sessions
-        manager.start();
-        
-        HashedSession restoredSession = (HashedSession)manager.getSession(sessionId);
-        Assert.assertNotNull(restoredSession);
-        
-        Object o = restoredSession.getAttribute("one");
-        Assert.assertNotNull(o);
-        
-        Assert.assertEquals(1, ((Integer)o).intValue());
-        Assert.assertEquals(5, restoredSession.getMaxInactiveInterval());     
-        
-        server.stop();
-    }
-}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
index 0004a15..2869657 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
@@ -30,6 +30,7 @@
 import javax.servlet.http.HttpSession;
 
 import org.eclipse.jetty.http.HttpCookie;
+import org.eclipse.jetty.server.Server;
 import org.junit.Test;
 
 /**
@@ -37,137 +38,118 @@
  */
 public class SessionCookieTest
 {
-    public class MockSession extends AbstractSession
+   
+    
+    
+    public class MockSessionStore extends AbstractSessionStore
     {
-        protected MockSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
-        {
-            super(abstractSessionManager, created, accessed, clusterId);
-        }
 
         /** 
-         * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String)
+         * @see org.eclipse.jetty.server.session.SessionStore#newSession(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
          */
         @Override
-        public Object getAttribute(String name)
+        public Session newSession(HttpServletRequest request, String key, long time, long maxInactiveMs)
         {
+            // TODO Auto-generated method stub
             return null;
         }
 
         /** 
-         * @see javax.servlet.http.HttpSession#getAttributeNames()
+         * @see org.eclipse.jetty.server.session.SessionStore#shutdown()
          */
         @Override
-        public Enumeration<String> getAttributeNames()
+        public void shutdown()
         {
-            return null;
-        }
-
-        @Override
-        public String[] getValueNames()
-        {
-            return null;
-        }
-
-        /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#getAttributeMap()
-         */
-        @Override
-        public Map<String, Object> getAttributeMap()
-        {
-            return null;
-        }
-
-        /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#getAttributes()
-         */
-        @Override
-        public int getAttributes()
-        {
-            return 0;
-        }
-
-        /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#getNames()
-         */
-        @Override
-        public Set<String> getNames()
-        {
-            return null;
-        }
-
-        /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#clearAttributes()
-         */
-        @Override
-        public void clearAttributes()
-        {
+            // TODO Auto-generated method stub
             
         }
 
         /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#doPutOrRemove(java.lang.String, java.lang.Object)
+         * @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.SessionData)
          */
         @Override
-        public Object doPutOrRemove(String name, Object value)
+        public Session newSession(SessionData data)
+        {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        /** 
+         * @see org.eclipse.jetty.server.session.AbstractSessionStore#doGet(org.eclipse.jetty.server.session.SessionKey)
+         */
+        @Override
+        public Session doGet(String key)
+        {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        /** 
+         * @see org.eclipse.jetty.server.session.AbstractSessionStore#doPutIfAbsent(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.Session)
+         */
+        @Override
+        public Session doPutIfAbsent(String key, Session session)
         {
             return null;
         }
 
         /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#doGet(java.lang.String)
+         * @see org.eclipse.jetty.server.session.AbstractSessionStore#doExists(org.eclipse.jetty.server.session.SessionKey)
          */
         @Override
-        public Object doGet(String name)
+        public boolean doExists(String key)
+        {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        /** 
+         * @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(org.eclipse.jetty.server.session.SessionKey)
+         */
+        @Override
+        public Session doDelete(String key)
         {
             return null;
         }
 
         /** 
-         * @see org.eclipse.jetty.server.session.AbstractSession#doGetAttributeNames()
+         * @see org.eclipse.jetty.server.session.AbstractSessionStore#doGetExpiredCandidates()
          */
         @Override
-        public Enumeration<String> doGetAttributeNames()
+        public Set<String> doGetExpiredCandidates()
         {
+            // TODO Auto-generated method stub
             return null;
-        }
-
+        } 
     }
 
+    
+    
     public class MockSessionIdManager extends AbstractSessionIdManager
     {
 
         /**
-         * @see org.eclipse.jetty.server.SessionIdManager#idInUse(java.lang.String)
+         * @param server
+         */
+        public MockSessionIdManager(Server server)
+        {
+            super(server);
+        }
+
+        /**
+         * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
          */
         @Override
-        public boolean idInUse(String id)
+        public boolean isIdInUse(String id)
         {
             return false;
         }
 
         /**
-         * @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
+         * @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
          */
         @Override
-        public void addSession(HttpSession session)
-        {
-
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
-         */
-        @Override
-        public void removeSession(HttpSession session)
-        {
-
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
-         */
-        @Override
-        public void invalidateAll(String id)
+        public void expireAll(String id)
         {
 
         }
@@ -179,73 +161,49 @@
             
         }
 
-    }
-
-    public class MockSessionManager extends AbstractSessionManager
-    {
-
-        /**
-         * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession)
+        /** 
+         * @see org.eclipse.jetty.server.SessionIdManager#useId(java.lang.String)
          */
         @Override
-        protected void addSession(AbstractSession session)
-        {
-
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String)
-         */
-        @Override
-        public AbstractSession getSession(String idInCluster)
-        {
-            return null;
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.session.AbstractSessionManager#shutdownSessions()
-         */
-        @Override
-        protected void shutdownSessions() throws Exception
-        {
-
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest)
-         */
-        @Override
-        protected AbstractSession newSession(HttpServletRequest request)
-        {
-            return null;
-        }
-
-        /**
-         * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String)
-         */
-        @Override
-        protected boolean removeSession(String idInCluster)
-        {
-            return false;
-        }
-
-        @Override
-        public void renewSessionId(String oldClusterId, String oldNodeId, String newClusterId, String newNodeId)
+        public void useId(Session session)
         {
             // TODO Auto-generated method stub
             
         }
 
+        /** 
+         * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String)
+         */
+        @Override
+        public boolean removeId(String id)
+        {
+            return true;
+        }
     }
+    
+    public class MockSessionManager extends SessionManager
+    {
+        public MockSessionManager()
+        {
+            _sessionStore = new MockSessionStore();
+            ((AbstractSessionStore)_sessionStore).setSessionDataStore(new NullSessionDataStore());
+        }
+    }
+
+  
 
     @Test
     public void testSecureSessionCookie () throws Exception
     {
-        MockSessionIdManager idMgr = new MockSessionIdManager();
+        Server server = new Server();
+        MockSessionIdManager idMgr = new MockSessionIdManager(server);
         idMgr.setWorkerName("node1");
         MockSessionManager mgr = new MockSessionManager();
         mgr.setSessionIdManager(idMgr);
-        MockSession session = new MockSession(mgr, System.currentTimeMillis(), System.currentTimeMillis(), "node1123"); //clusterId
+        
+        long now = System.currentTimeMillis();
+        
+        Session session = new Session(new SessionData("123", "_foo", "0.0.0.0", now, now, now, 30)); 
 
         SessionCookieConfig sessionCookieConfig = mgr.getSessionCookieConfig();
         sessionCookieConfig.setSecure(true);
diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml
index a3dda9f..18eb626 100644
--- a/tests/test-sessions/pom.xml
+++ b/tests/test-sessions/pom.xml
@@ -32,6 +32,7 @@
   <modules>
     <module>test-sessions-common</module>
     <module>test-hash-sessions</module>
+    <module>test-file-sessions</module>
     <module>test-jdbc-sessions</module>
     <module>test-mongodb-sessions</module>
     <module>test-infinispan-sessions</module>
diff --git a/tests/test-sessions/test-file-sessions/.gitignore b/tests/test-sessions/test-file-sessions/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/tests/test-sessions/test-file-sessions/pom.xml b/tests/test-sessions/test-file-sessions/pom.xml
new file mode 100644
index 0000000..f937ef4
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+// ========================================================================
+// Copyright (c) Webtide LLC
+// 
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at 
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.apache.org/licenses/LICENSE-2.0.txt
+//
+// You may elect to redistribute this code under either of these licenses. 
+// ========================================================================
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.jetty.tests</groupId>
+    <artifactId>test-sessions-parent</artifactId>
+    <version>9.3.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>test-file-sessions</artifactId>
+  <name>Jetty Tests :: Sessions :: File</name>
+  <url>http://www.eclipse.org/jetty</url>
+  <properties>
+    <bundle-symbolic-name>${project.groupId}.sessions.file</bundle-symbolic-name>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <!-- DO NOT DEPLOY (or Release) -->
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+       <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.tests</groupId>
+            <artifactId>test-sessions-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty.toolchain</groupId>
+      <artifactId>jetty-test-helper</artifactId>
+      <!-- Leaving at compile scope for intellij bug reasons -->
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
new file mode 100644
index 0000000..c10d815
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
@@ -0,0 +1,54 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import java.io.File;
+
+import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClientCrossContextSessionTest extends AbstractClientCrossContextSessionTest
+{
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    public AbstractTestServer createServer(int port)
+    {
+        return new FileTestServer(port);
+    }
+
+    @Test
+    public void testCrossContextDispatch() throws Exception
+    {
+        super.testCrossContextDispatch();
+    }
+
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java
new file mode 100644
index 0000000..c3c89a4
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java
@@ -0,0 +1,84 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import java.io.File;
+
+import org.eclipse.jetty.server.SessionIdManager;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.util.IO;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class FileTestServer extends AbstractTestServer
+{
+    static int __workers=0;
+    static File _tmpDir;
+    
+    public  static void setup ()
+    throws Exception
+    {
+        
+        _tmpDir = File.createTempFile("file", null);
+        _tmpDir.delete();
+        _tmpDir.mkdirs();
+        _tmpDir.deleteOnExit();
+    }
+    
+    
+    public static void teardown ()
+    {
+        IO.delete(_tmpDir);
+        _tmpDir = null;
+    }
+    
+    
+    
+    public FileTestServer(int port)
+    {
+        super(port, 30, 10);
+    }
+
+    public FileTestServer(int port, int maxInactivePeriod, int scavengePeriod)
+    {
+        super(port, maxInactivePeriod, scavengePeriod);
+    }
+
+
+    public SessionIdManager newSessionIdManager(Object config)
+    {
+        HashSessionIdManager mgr = new HashSessionIdManager(_server);
+        mgr.setWorkerName("worker"+(__workers++));
+        return mgr;
+    }
+
+    public SessionManager newSessionManager()
+    {
+        FileSessionManager manager = new FileSessionManager();
+        manager.getSessionDataStore().setStoreDir(_tmpDir);
+        return manager;
+    }
+
+    public SessionHandler newSessionHandler(SessionManager sessionManager)
+    {
+        return new SessionHandler(sessionManager);
+    }
+
+}
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ForwardedSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ForwardedSessionTest.java
similarity index 60%
rename from tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ForwardedSessionTest.java
rename to tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ForwardedSessionTest.java
index 48bcf5a..f16bb08 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ForwardedSessionTest.java
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ForwardedSessionTest.java
@@ -19,10 +19,6 @@
 
 package org.eclipse.jetty.server.session;
 
-import java.io.File;
-
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.util.IO;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -34,47 +30,23 @@
  */
 public class ForwardedSessionTest extends AbstractForwardedSessionTest
 { 
-   File tmpDir;
     
     @Before
     public void before() throws Exception
     {
-        tmpDir = File.createTempFile("hash-session-forward-test", null);
-        tmpDir.delete();
-        tmpDir.mkdirs();
-        tmpDir.deleteOnExit();
+       FileTestServer.setup();
     }
     
     @After 
     public void after()
     {
-        IO.delete(tmpDir);
+        FileTestServer.teardown();
     }
     
     @Override
     public AbstractTestServer createServer(int port)
     {
-        return new HashTestServer(port)
-        {
-
-            @Override
-            public SessionManager newSessionManager()
-            {
-                HashSessionManager sessionManager = (HashSessionManager)super.newSessionManager();
-                sessionManager.setSavePeriod(2);
-                
-                try
-                {
-                    sessionManager.setStoreDirectory(tmpDir);
-                }
-                catch (Exception e)
-                {
-                    throw new IllegalStateException(e);
-                }
-                return sessionManager;
-            }
-
-        };
+        return new FileTestServer(port);
     }
 
     
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java
new file mode 100644
index 0000000..b044301
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ImmortalSessionTest.java
@@ -0,0 +1,45 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+
+public class ImmortalSessionTest extends AbstractImmortalSessionTest
+{
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    
+    @Override
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port,max,scavenge);
+    }
+
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
new file mode 100644
index 0000000..6076ae0
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/NewSessionTest.java
@@ -0,0 +1,53 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * NewSessionTest
+ */
+public class NewSessionTest extends AbstractNewSessionTest
+{
+    @Before
+    public void before() throws Exception
+    {
+        System.setProperty("org.eclipse.jetty.server.session.LEVEL", "DEBUG");
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port,max,scavenge);
+    }
+
+    @Test
+    public void testNewSession() throws Exception
+    {
+        super.testNewSession();
+    }
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
new file mode 100644
index 0000000..c34c7cb
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/OrphanedSessionTest.java
@@ -0,0 +1,52 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * OrphanedSessionTest
+ */
+public class OrphanedSessionTest extends AbstractOrphanedSessionTest
+{
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+       return new FileTestServer(port,max,scavenge);
+    }
+
+    @Test
+    public void testOrphanedSession() throws Exception
+    {
+        super.testOrphanedSession();
+    }
+}
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ProxySerializationTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ProxySerializationTest.java
similarity index 71%
rename from tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ProxySerializationTest.java
rename to tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ProxySerializationTest.java
index d01cb17..7c48b87 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ProxySerializationTest.java
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ProxySerializationTest.java
@@ -23,6 +23,8 @@
 
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -32,40 +34,29 @@
  */
 public class ProxySerializationTest extends AbstractProxySerializationTest
 {   
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
     /** 
      * @see org.eclipse.jetty.server.session.AbstractProxySerializationTest#createServer(int, int, int)
      */
     @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
-        return new HashTestServer(port,max,scavenge);
+        return new FileTestServer(port,max,scavenge);
     }
     
     
     
-    
-    @Override
-    public void customizeContext(ServletContextHandler c)
-    {
-        if (c == null)
-            return;
-        
-        //Ensure that the HashSessionManager will persist sessions on passivation
-        HashSessionManager manager = (HashSessionManager)c.getSessionHandler().getSessionManager();
-        manager.setLazyLoad(false);
-        manager.setIdleSavePeriod(1);
-        try
-        {
-            File testDir = MavenTestingUtils.getTargetTestingDir("foo");
-            testDir.mkdirs();
-            manager.setStoreDirectory(testDir);
-        }
-        catch (Exception e)
-        {
-            throw new IllegalStateException(e);
-        }       
-    }
-
 
 
 
@@ -75,4 +66,14 @@
         super.testProxySerialization();
     }
 
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractProxySerializationTest#customizeContext(org.eclipse.jetty.servlet.ServletContextHandler)
+     */
+    @Override
+    public void customizeContext(ServletContextHandler c)
+    {
+        // TODO Auto-generated method stub
+        
+    }
+
 }
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
new file mode 100644
index 0000000..147c63e
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ReentrantRequestSessionTest.java
@@ -0,0 +1,54 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * ReentrantRequestSessionTest
+ */
+public class ReentrantRequestSessionTest extends AbstractReentrantRequestSessionTest
+{
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    public AbstractTestServer createServer(int port)
+    {
+        return new FileTestServer(port);
+    }
+
+    @Test
+    public void testReentrantRequestSession() throws Exception
+    {
+        super.testReentrantRequestSession();
+    }
+
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java
new file mode 100644
index 0000000..a6e1511
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/RemoveSessionTest.java
@@ -0,0 +1,52 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RemoveSessionTest extends AbstractRemoveSessionTest
+{ 
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port,max,scavenge);
+    }
+    
+    @Test
+    public void testRemoveSession() throws Exception
+    {
+        super.testRemoveSession();
+    }
+
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ScatterGunLoadTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ScatterGunLoadTest.java
new file mode 100644
index 0000000..9a990f3
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ScatterGunLoadTest.java
@@ -0,0 +1,55 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * ScatterGunLoadTest
+ */
+public class ScatterGunLoadTest extends AbstractScatterGunLoadTest
+{
+
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    public AbstractTestServer createServer(int port)
+    {
+        return new FileTestServer(port);
+    }
+
+    @Test
+    public void testLightLoad() throws Exception
+    {
+        super.testLightLoad();
+    }
+
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
new file mode 100644
index 0000000..35c6492
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/ServerCrossContextSessionTest.java
@@ -0,0 +1,51 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServerCrossContextSessionTest extends AbstractServerCrossContextSessionTest
+{
+
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    public AbstractTestServer createServer(int port)
+    {
+        return new FileTestServer(port);
+    }
+
+    @Test
+    public void testCrossContextDispatch() throws Exception
+    {
+        super.testCrossContextDispatch();
+    }
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
new file mode 100644
index 0000000..8a7ae51
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java
@@ -0,0 +1,48 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+
+public class SessionCookieTest extends AbstractSessionCookieTest
+{
+
+
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    
+    @Override
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port, max, scavenge);
+    }
+
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateAndCreateTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateAndCreateTest.java
new file mode 100644
index 0000000..c28a156
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionInvalidateAndCreateTest.java
@@ -0,0 +1,51 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SessionInvalidateAndCreateTest extends AbstractSessionInvalidateAndCreateTest
+{
+
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+       FileTestServer.teardown();
+    }
+    
+    @Override
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port,max,scavenge);
+    }
+    
+    @Test
+    public void testSessionScavenge() throws Exception
+    {
+        super.testSessionScavenge();
+    }
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
new file mode 100644
index 0000000..e9a1b46
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
@@ -0,0 +1,58 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import java.io.File;
+
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SessionRenewTest extends AbstractSessionRenewTest
+{
+   
+    
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+        FileTestServer.teardown();
+    }
+    
+    @Override
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port, max, scavenge);
+    }
+
+    @Test
+    public void testSessionRenewal() throws Exception
+    {
+        super.testSessionRenewal();
+    }
+
+    
+}
diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionValueSharedSaving.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionValueSharedSaving.java
new file mode 100644
index 0000000..d22537d
--- /dev/null
+++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionValueSharedSaving.java
@@ -0,0 +1,46 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.server.session;
+
+import org.junit.After;
+import org.junit.Before;
+
+public class SessionValueSharedSaving extends AbstractSessionValueSavingTest
+{
+
+    @Before
+    public void before() throws Exception
+    {
+       FileTestServer.setup();
+    }
+    
+    @After 
+    public void after()
+    {
+        FileTestServer.teardown();
+    }
+    
+    
+    @Override
+    public AbstractTestServer createServer(int port, int max, int scavenge)
+    {
+        return new FileTestServer(port,max,scavenge);
+    }
+
+}
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java
index f30996b..38bfa57 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTestSupport.java
@@ -295,7 +295,7 @@
     public void listSessions () throws Exception
     {
         ensureDatastore();
-        GqlQuery.Builder builder = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from "+GCloudSessionManager.KIND);
+        GqlQuery.Builder builder = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from "+GCloudSessionDataStore.KIND);
        
         Query<Entity> query = builder.build();
     
@@ -315,7 +315,7 @@
     {
         ensureDatastore();
         StructuredQuery<ProjectionEntity> keyOnlyProjectionQuery = Query.projectionEntityQueryBuilder()
-                .kind(GCloudSessionManager.KIND)
+                .kind(GCloudSessionDataStore.KIND)
                 .projection(Projection.property("__key__"))
                 .limit(100)
                 .build();  
@@ -334,7 +334,7 @@
     {
        ensureDatastore();
         StructuredQuery<ProjectionEntity> keyOnlyProjectionQuery = Query.projectionEntityQueryBuilder()
-                .kind(GCloudSessionManager.KIND)
+                .kind(GCloudSessionDataStore.KIND)
                 .projection(Projection.property("__key__"))
                 .limit(100)
                 .build();  
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java
index 11f2125..96a8418 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java
@@ -21,8 +21,10 @@
 
 import org.eclipse.jetty.server.SessionIdManager;
 import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.session.AbstractSessionStore;
 import org.eclipse.jetty.server.session.AbstractTestServer;
 import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.server.session.StalePeriodStrategy;
 
 import com.google.gcloud.datastore.Datastore;
 import com.google.gcloud.datastore.DatastoreFactory;
@@ -79,8 +81,10 @@
     {
         GCloudSessionManager sessionManager = new GCloudSessionManager();
         sessionManager.setSessionIdManager((GCloudSessionIdManager)_sessionIdManager);
-        sessionManager.setStaleIntervalSec(STALE_INTERVAL_SEC);
-        sessionManager.setScavengeIntervalSec(_scavengePeriod);
+        sessionManager.getSessionDataStore().setGCloudConfiguration(((GCloudSessionIdManager)_sessionIdManager).getConfig());
+        StalePeriodStrategy staleStrategy = new StalePeriodStrategy();
+        staleStrategy.setStaleSec(STALE_INTERVAL_SEC);
+       ((AbstractSessionStore)sessionManager.getSessionStore()).setStaleStrategy(staleStrategy);
         return sessionManager;
         
     }
diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ImmortalSessionTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ImmortalSessionTest.java
index 54e983e..153a07e 100644
--- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ImmortalSessionTest.java
+++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/ImmortalSessionTest.java
@@ -55,7 +55,7 @@
     @Override
     public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs)
     {
-       return new GCloudTestServer(port, port, scavengeMs, _testSupport.getConfiguration());
+       return new GCloudTestServer(port, maxInactiveMs, scavengeMs, _testSupport.getConfiguration());
     }
 
     @Test
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
index acb3403..46a3e5b 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/ClientCrossContextSessionTest.java
@@ -18,14 +18,16 @@
 
 package org.eclipse.jetty.server.session;
 
+import java.io.File;
+
+import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
 public class ClientCrossContextSessionTest extends AbstractClientCrossContextSessionTest
 {
-    public AbstractTestServer createServer(int port)
-    {
-        return new HashTestServer(port);
-    }
+
 
     @Test
     public void testCrossContextDispatch() throws Exception
@@ -33,4 +35,13 @@
         super.testCrossContextDispatch();
     }
 
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractClientCrossContextSessionTest#createServer(int)
+     */
+    @Override
+    public AbstractTestServer createServer(int port)
+    {
+        return new HashTestServer(port);
+    }
+
 }
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java
index 3393d8e..11e3f5e 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java
@@ -26,7 +26,8 @@
  */
 public class HashTestServer extends AbstractTestServer
 {
-
+    static int __workers=0;
+    
     public HashTestServer(int port)
     {
         super(port, 30, 10);
@@ -40,13 +41,14 @@
 
     public SessionIdManager newSessionIdManager(Object config)
     {
-        return new HashSessionIdManager();
+        HashSessionIdManager mgr = new HashSessionIdManager(_server);
+        mgr.setWorkerName("worker"+(__workers++));
+        return mgr;
     }
 
     public SessionManager newSessionManager()
     {
         HashSessionManager manager = new HashSessionManager();
-        manager.setScavengePeriod(_scavengePeriod);
         return manager;
     }
 
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java
index 30ff2d1..331d603 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/IdleSessionTest.java
@@ -47,6 +47,8 @@
  * IdleSessionTest
  *
  * Checks that a session can be idled and de-idled on the next request if it hasn't expired.
+ * 
+ * TODO support session idling in FileSessionDataStore?
  *
  */
 public class IdleSessionTest
@@ -67,17 +69,10 @@
         @Override
         public SessionManager newSessionManager()
         {
-            try
-            {
-                HashSessionManager manager = (HashSessionManager)super.newSessionManager();
-                manager.setStoreDirectory(_storeDir);
-                manager.setIdleSavePeriod(_idlePeriod);
-                return manager;
-            }
-            catch ( IOException e)
-            {
-                return null;
-            }
+            HashSessionManager manager = (HashSessionManager)super.newSessionManager();
+            //manager.getSessionDataStore().setStoreDir(_storeDir);
+            //manager.setIdleSavePeriod(_idlePeriod);
+            return manager;
         }
 
 
@@ -103,7 +98,6 @@
         }
     }
 
-    @Test
     public void testSessionIdle() throws Exception
     {
         String contextPath = "";
@@ -111,7 +105,7 @@
         int inactivePeriod = 200;
         int scavengePeriod = 3;
         int idlePeriod = 5;
-        ((StdErrLog)Log.getLogger(org.eclipse.jetty.server.session.HashedSession.class)).setHideStacks(true);
+        ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.session")).setHideStacks(true);
         System.setProperty("org.eclipse.jetty.STACKS", "false");
         File storeDir = new File (System.getProperty("java.io.tmpdir"), "idle-test");
         storeDir.deleteOnExit();
@@ -229,7 +223,7 @@
                 HttpSession session = request.getSession(true);
                 session.setAttribute("test", "test");
                 originalId = session.getId();
-                assertTrue(!((HashedSession)session).isIdled());
+//                assertTrue(!((HashedSession)session).isIdled());
             }
             else if ("test".equals(action))
             {
@@ -237,7 +231,7 @@
                 assertTrue(session != null);
                 assertTrue(originalId.equals(session.getId()));
                 assertEquals("test", session.getAttribute("test"));
-                assertTrue(!((HashedSession)session).isIdled());
+ //               assertTrue(!((HashedSession)session).isIdled());
             }
             else if ("testfail".equals(action))
             {
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
index 207dbdb..9391cbf 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
@@ -28,47 +28,11 @@
 
 public class SessionRenewTest extends AbstractSessionRenewTest
 {
-    File tmpDir;
-    
-    @Before
-    public void before() throws Exception
-    {
-        tmpDir = File.createTempFile("hash-session-renew-test", null);
-        tmpDir.delete();
-        tmpDir.mkdirs();
-        tmpDir.deleteOnExit();
-    }
-    
-    @After 
-    public void after()
-    {
-        IO.delete(tmpDir);
-    }
     
     @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
-        return new HashTestServer(port, max, scavenge)
-        {
-
-            @Override
-            public SessionManager newSessionManager()
-            {
-                HashSessionManager sessionManager = (HashSessionManager)super.newSessionManager();
-                sessionManager.setSavePeriod(2);
-                
-                try
-                {
-                    sessionManager.setStoreDirectory(tmpDir);
-                }
-                catch (Exception e)
-                {
-                    throw new IllegalStateException(e);
-                }
-                return sessionManager;
-            }
-
-        };
+        return new HashTestServer(port, max, scavenge);
     }
 
     @Test
diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java
index c6b2122..7b803f5 100644
--- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java
+++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java
@@ -63,10 +63,10 @@
     {
         InfinispanSessionManager sessionManager = new InfinispanSessionManager();
         sessionManager.setSessionIdManager((InfinispanSessionIdManager)_sessionIdManager);
-        sessionManager.setCache(((InfinispanSessionIdManager)_sessionIdManager).getCache());
-        sessionManager.setStaleIntervalSec(1);
-        sessionManager.setScavengeInterval(_scavengePeriod);
-        
+        sessionManager.getSessionDataStore().setCache(((InfinispanSessionIdManager)_sessionIdManager).getCache());
+        StalePeriodStrategy staleStrategy = new StalePeriodStrategy();
+        staleStrategy.setStaleSec(1);
+       ((AbstractSessionStore)sessionManager.getSessionStore()).setStaleStrategy(staleStrategy);
         return sessionManager;
     }
 
diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java
index a3b61bd..04a3fed 100644
--- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java
+++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java
@@ -88,7 +88,6 @@
         _tmpdir = File.createTempFile("infini", "span");
         _tmpdir.delete();
         _tmpdir.mkdir();
-        System.err.println("Temp file: "+_tmpdir);
         Configuration config = _builder.persistence().addSingleFileStore().location(_tmpdir.getAbsolutePath()).storeAsBinary().build();
         _manager.defineConfiguration(_name, config);
        }
diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java
index bb09b64..9fe361d 100644
--- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java
+++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/LastAccessTimeTest.java
@@ -52,14 +52,5 @@
     {
         super.testLastAccessTime();
     }
-
-    @Override
-    public void assertAfterScavenge(AbstractSessionManager manager)
-    {
-        //The infinispan session manager will remove a session from its local memory that was a candidate to be scavenged if
-        //it checks with the cluster and discovers that another node is managing it, so the count is 0
-        assertSessionCounts(0, 1, 1, manager);
-    }
-
     
 }
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java
index dd68fff..e98f1d3 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/InvalidationSessionTest.java
@@ -40,7 +40,7 @@
         //that the node will re-load the session from the database and discover that it has gone.
         try
         {
-            Thread.sleep(2 * JdbcTestServer.SAVE_INTERVAL * 1000);
+            Thread.sleep(2 * JdbcTestServer.STALE_INTERVAL * 1000);
         }
         catch (InterruptedException e)
         {
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java
index 03e9ff1..7da1e5d 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java
@@ -38,8 +38,21 @@
     public static final String DRIVER_CLASS = "org.apache.derby.jdbc.EmbeddedDriver";
     public static final String DEFAULT_CONNECTION_URL = "jdbc:derby:memory:sessions;create=true";
     public static final String DEFAULT_SHUTDOWN_URL = "jdbc:derby:memory:sessions;drop=true";
-    public static final int SAVE_INTERVAL = 1;
+    public static final int STALE_INTERVAL = 1;
     
+
+    public static final String EXPIRY_COL = "extime";
+    public static final String LAST_ACCESS_COL = "latime";
+    public static final String LAST_NODE_COL = "lnode";
+    public static final String LAST_SAVE_COL = "lstime";
+    public static final String MAP_COL = "mo";
+    public static final String MAX_IDLE_COL = "mi";  
+    public static final String TABLE = "mysessions";
+    public static final String ID_COL = "mysessionid";
+    public static final String ACCESS_COL = "atime";
+    public static final String CONTEXT_COL = "cpath";
+    public static final String COOKIE_COL = "cooktime";
+    public static final String CREATE_COL = "ctime";
     
     static 
     {
@@ -103,28 +116,14 @@
         synchronized(JdbcTestServer.class)
         {
             JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server);
-            idManager.setScavengeInterval(_scavengePeriod);
             idManager.setWorkerName("w"+(__workers++));
-            idManager.setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:(String)config));
+            idManager.getDatabaseAdaptor().setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:(String)config));
             JDBCSessionIdManager.SessionIdTableSchema idTableSchema = new JDBCSessionIdManager.SessionIdTableSchema();
             idTableSchema.setTableName("mysessionids");
             idTableSchema.setIdColumn("myid");
-            idManager.setSessionIdTableSchema(idTableSchema);
-            
-            JDBCSessionIdManager.SessionTableSchema sessionTableSchema = new JDBCSessionIdManager.SessionTableSchema();
-            sessionTableSchema.setTableName("mysessions");
-            sessionTableSchema.setIdColumn("mysessionid");
-            sessionTableSchema.setAccessTimeColumn("atime");
-            sessionTableSchema.setContextPathColumn("cpath");
-            sessionTableSchema.setCookieTimeColumn("cooktime");
-            sessionTableSchema.setCreateTimeColumn("ctime");
-            sessionTableSchema.setExpiryTimeColumn("extime");
-            sessionTableSchema.setLastAccessTimeColumn("latime");
-            sessionTableSchema.setLastNodeColumn("lnode");
-            sessionTableSchema.setLastSavedTimeColumn("lstime");
-            sessionTableSchema.setMapColumn("mo");
-            sessionTableSchema.setMaxIntervalColumn("mi");           
-            idManager.setSessionTableSchema(sessionTableSchema);
+
+    
+
             
             return idManager;
         }
@@ -133,12 +132,34 @@
     /** 
      * @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionManager()
      */
+    /** 
+     * @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionManager()
+     */
     @Override
     public SessionManager newSessionManager()
     {
         JDBCSessionManager manager =  new JDBCSessionManager();
         manager.setSessionIdManager((JDBCSessionIdManager)_sessionIdManager);
-        manager.setSaveInterval(SAVE_INTERVAL); //ensure we save any changes to the session at least once per second
+        JDBCSessionDataStore ds = manager.getSessionDataStore();
+        ds.setGracePeriodSec(_scavengePeriod);
+        manager.getDatabaseAdaptor().setDriverInfo(DRIVER_CLASS, DEFAULT_CONNECTION_URL);
+        JDBCSessionDataStore.SessionTableSchema sessionTableSchema = new JDBCSessionDataStore.SessionTableSchema();
+        sessionTableSchema.setTableName(TABLE);
+        sessionTableSchema.setIdColumn(ID_COL);
+        sessionTableSchema.setAccessTimeColumn(ACCESS_COL);
+        sessionTableSchema.setContextPathColumn(CONTEXT_COL);
+        sessionTableSchema.setCookieTimeColumn(COOKIE_COL);
+        sessionTableSchema.setCreateTimeColumn(CREATE_COL);
+        sessionTableSchema.setExpiryTimeColumn(EXPIRY_COL);
+        sessionTableSchema.setLastAccessTimeColumn(LAST_ACCESS_COL);
+        sessionTableSchema.setLastNodeColumn(LAST_NODE_COL);
+        sessionTableSchema.setLastSavedTimeColumn(LAST_SAVE_COL);
+        sessionTableSchema.setMapColumn(MAP_COL);
+        sessionTableSchema.setMaxIntervalColumn(MAX_IDLE_COL);       
+        ds.setSessionTableSchema(sessionTableSchema);
+        StalePeriodStrategy staleStrategy = new StalePeriodStrategy();
+        staleStrategy.setStaleSec(STALE_INTERVAL);
+       ((AbstractSessionStore)manager.getSessionStore()).setStaleStrategy(staleStrategy);
         return manager;
     }
 
@@ -175,8 +196,8 @@
         {
             con = DriverManager.getConnection(DEFAULT_CONNECTION_URL);
             PreparedStatement statement = con.prepareStatement("select * from "+
-                    ((JDBCSessionIdManager)_sessionIdManager)._sessionTableSchema.getTableName()+
-                    " where "+((JDBCSessionIdManager)_sessionIdManager)._sessionTableSchema.getIdColumn()+" = ?");
+                    TABLE+
+                    " where "+ID_COL+" = ?");
             statement.setString(1, id);
             ResultSet result = statement.executeQuery();
             if (verbose)
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java
index d777a61..5bf8eec 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ModifyMaxInactiveIntervalTest.java
@@ -75,7 +75,7 @@
                 assertTrue(sessionCookie != null);
                 // Mangle the cookie, replacing Path with $Path, etc.
                 sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
-                
+
                 //do another request to change the maxinactive interval
                 Request request = client.newRequest("http://localhost:" + port + "/mod/test?action=change&val="+newMaxInactive);
                 request.header("Cookie", sessionCookie);
@@ -87,7 +87,6 @@
                 Thread.currentThread().sleep(10*1000L);
                 
                 //do another request using the cookie to ensure the session is still there
-               
                 request= client.newRequest("http://localhost:" + port + "/mod/test?action=test");
                 request.header("Cookie", sessionCookie);
                 response = request.send();
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java
index 44acb9d..6d4917c 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java
@@ -53,7 +53,7 @@
     @Test
     public void testSessionReloadWithMissingClass() throws Exception
     {
-        ((StdErrLog)Log.getLogger(org.eclipse.jetty.server.session.JDBCSessionManager.class)).setHideStacks(true);
+        ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.session")).setHideStacks(true);
         Resource.setDefaultUseCaches(false);
         String contextPath = "/foo";
 
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SaveIntervalTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SaveIntervalTest.java
index e031b29..0583c20 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SaveIntervalTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SaveIntervalTest.java
@@ -43,7 +43,7 @@
  *  SaveIntervalTest
  *
  *  Checks to see that potentially stale sessions that have not
- *  changed are not always reloaded from the datase.
+ *  changed are not always reloaded from the database.
  *
  *  This test is Ignored because it takes a little while to run.
  *
@@ -66,7 +66,10 @@
         TestSaveIntervalServlet servlet = new TestSaveIntervalServlet();
         holder.setServlet(servlet);
         ctxA.addServlet(holder, "/test");
-        ((JDBCSessionManager)ctxA.getSessionHandler().getSessionManager()).setSaveInterval(SAVE);
+
+        StalePeriodStrategy strategy = new StalePeriodStrategy();
+        strategy.setStaleSec(SAVE);
+       ((AbstractSessionStore)((JDBCSessionManager)ctxA.getSessionHandler().getSessionManager()).getSessionStore()).setStaleStrategy(strategy);
         server.start();
         int port=server.getPort();
         try
@@ -82,7 +85,7 @@
                 assertTrue(sessionCookie != null);
                 // Mangle the cookie, replacing Path with $Path, etc.
                 sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
-                long lastSaved = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
+                long lastSaved = ((Session)servlet._session).getSessionData().getLastSaved();
                 
                 
                 //do another request to change the session attribute
@@ -90,7 +93,7 @@
                 request.header("Cookie", sessionCookie);
                 response = request.send();
                 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-                long tmp = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
+                long tmp = ((Session)servlet._session).getSessionData().getLastSaved();
                 assertNotEquals(lastSaved, tmp); //set of attribute will cause save to db
                 lastSaved = tmp;
                 
@@ -106,7 +109,7 @@
                 request.header("Cookie", sessionCookie);
                 response = request.send();
                 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-                tmp = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
+                tmp = ((Session)servlet._session).getSessionData().getLastSaved();
                 assertNotEquals(lastSaved, tmp);
                 lastSaved = tmp;
               
@@ -120,7 +123,7 @@
                 request.header("Cookie", sessionCookie);
                 response = request.send();
                 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-                tmp = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
+                tmp = ((Session)servlet._session).getSessionData().getLastSaved();
                 assertEquals(lastSaved, tmp); //the save interval did not expire, so update to the access time will not have been persisted
             }
             finally
@@ -154,7 +157,6 @@
             if ("create".equals(action))
             {
                 HttpSession session = request.getSession(true);
-                System.err.println("CREATE: Session id="+session.getId());
                 _session = session;
                 return;
             }
@@ -164,8 +166,7 @@
                 HttpSession session = request.getSession(false);
                 if (session == null)
                     throw new ServletException("Session is null for action=change");
-               
-                System.err.println("SET: Session id="+session.getId());
+
                 session.setAttribute("aaa", "12345");
                 assertEquals(_session.getId(), session.getId());
                 return;
@@ -176,7 +177,7 @@
                 HttpSession session = request.getSession(false);
                 if (session == null)
                     throw new ServletException("Session does not exist");
-                System.err.println("TICKLE: Session id="+session.getId());
+
                 assertEquals(_session.getId(), session.getId());
                 return;
             }
diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/StopSessionManagerPreserveSessionTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/StopSessionManagerPreserveSessionTest.java
index 1c43a75..2725f87 100644
--- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/StopSessionManagerPreserveSessionTest.java
+++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/StopSessionManagerPreserveSessionTest.java
@@ -42,7 +42,6 @@
         try
         {
             boolean actual = _server.existsInSessionTable(_id, true);
-            System.err.println(expected+":"+actual);
             assertEquals(expected, actual);
         }
         catch (Exception e)
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java
index 5ed5020..c4f6202 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/AttributeNameTest.java
@@ -34,8 +34,10 @@
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.client.api.Request;
 import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.nosql.NoSqlSession;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.eclipse.jetty.server.session.Session;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -48,7 +50,19 @@
 public class AttributeNameTest 
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
 
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
 
     public AbstractTestServer createServer(int port, int max, int scavenge)
     throws Exception
@@ -129,14 +143,14 @@
             String action = request.getParameter("action");
             if ("init".equals(action))
             {
-                NoSqlSession session = (NoSqlSession)request.getSession(true);
+                Session session = (Session)request.getSession(true);
                 session.setAttribute("a.b.c",System.currentTimeMillis());               
                 sendResult(session,httpServletResponse.getWriter());
-                
+
             }
             else
             {
-                NoSqlSession session = (NoSqlSession)request.getSession(false);
+                Session session = (Session)request.getSession(false);
                 assertNotNull(session);     
                 assertNotNull(session.getAttribute("a.b.c"));
                 sendResult(session,httpServletResponse.getWriter());
@@ -144,7 +158,7 @@
 
         }
 
-        private void sendResult(NoSqlSession session, PrintWriter writer)
+        private void sendResult(Session session, PrintWriter writer)
         {
             if (session != null)
             {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClientCrossContextSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClientCrossContextSessionTest.java
index 5879806..3f7a198 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClientCrossContextSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ClientCrossContextSessionTest.java
@@ -20,10 +20,26 @@
 
 import org.eclipse.jetty.server.session.AbstractClientCrossContextSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class ClientCrossContextSessionTest extends AbstractClientCrossContextSessionTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     public AbstractTestServer createServer(int port)
     {
         return new MongoTestServer(port);
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ForwardedSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ForwardedSessionTest.java
index 6cd4c59..a126442 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ForwardedSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ForwardedSessionTest.java
@@ -21,6 +21,8 @@
 
 import org.eclipse.jetty.server.session.AbstractForwardedSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -30,7 +32,21 @@
  */
 public class ForwardedSessionTest extends AbstractForwardedSessionTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
 
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
+    
     /** 
      * @see org.eclipse.jetty.server.session.AbstractForwardedSessionTest#createServer(int)
      */
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/InvalidateSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/InvalidateSessionTest.java
index c1e1c0f..73de70c 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/InvalidateSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/InvalidateSessionTest.java
@@ -21,11 +21,27 @@
 
 import org.eclipse.jetty.server.session.AbstractInvalidationSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class InvalidateSessionTest extends AbstractInvalidationSessionTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     @Override
     public AbstractTestServer createServer(int port)
     {
@@ -37,11 +53,10 @@
     {
         try
         {
-            Thread.currentThread().sleep(2000);
+            Thread.sleep(2 * MongoTestServer.STALE_INTERVAL * 1000);
         }
-        catch (Exception e)
+        catch (InterruptedException e)
         {
-            e.printStackTrace();
         }
     }
     
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LastAccessTimeTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LastAccessTimeTest.java
index bf86b5e..c84ef67 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LastAccessTimeTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LastAccessTimeTest.java
@@ -20,19 +20,40 @@
 
 import org.eclipse.jetty.server.session.AbstractLastAccessTimeTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class LastAccessTimeTest extends AbstractLastAccessTimeTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
         return new MongoTestServer(port,max,scavenge);
     }
 
+   
+    
+    
     @Test
     public void testLastAccessTime() throws Exception
     {
         super.testLastAccessTime();
     }
+
+ 
 }
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LocalSessionScavengingTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LocalSessionScavengingTest.java
index 6e38725..e1be78a 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LocalSessionScavengingTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/LocalSessionScavengingTest.java
@@ -20,15 +20,31 @@
 
 import org.eclipse.jetty.server.session.AbstractLocalSessionScavengingTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 
 public class LocalSessionScavengingTest extends AbstractLocalSessionScavengingTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
        MongoTestServer mserver=new MongoTestServer(port,max,scavenge);
-       ((MongoSessionIdManager)mserver.getServer().getSessionIdManager()).setScavengeBlockSize(0);
+       
        return mserver;
     }
 
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java
index 0ada08a..ee1597e 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java
@@ -20,15 +20,15 @@
 
 import java.net.UnknownHostException;
 
-import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.SessionIdManager;
 import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.session.AbstractSessionStore;
 import org.eclipse.jetty.server.session.AbstractTestServer;
 import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.server.session.StalePeriodStrategy;
 
-import com.mongodb.BasicDBObject;
-import com.mongodb.DBCursor;
-import com.mongodb.DBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.Mongo;
 import com.mongodb.MongoException;
 
 
@@ -37,32 +37,30 @@
  */
 public class MongoTestServer extends AbstractTestServer
 {
+    public static final int STALE_INTERVAL = 1;
     static int __workers=0;
-    private boolean _saveAllAttributes = false; // false save dirty, true save all
-    private int _saveInterval = 0;
     
     
-    public static class TestMongoSessionIdManager extends MongoSessionIdManager 
+    
+    public static void dropCollection () throws MongoException, UnknownHostException
     {
-
-        public TestMongoSessionIdManager(Server server) throws UnknownHostException, MongoException
-        {
-            super(server);
-        }
-        
-        
-        public void deleteAll ()
-        {
-            
-            DBCursor checkSessions = _sessions.find();
-
-            for (DBObject session : checkSessions)
-            {
-                _sessions.remove(session);
-            }
-        }
+        new Mongo().getDB("HttpSessions").getCollection("testsessions").drop();
     }
     
+    
+    public static void createCollection() throws UnknownHostException, MongoException
+    {
+        new Mongo().getDB("HttpSessions").createCollection("testsessions", null);
+    }
+    
+    
+    public static DBCollection getCollection () throws UnknownHostException, MongoException 
+    {
+        return new Mongo().getDB("HttpSessions").getCollection("testsessions");
+    }
+    
+
+    
     public MongoTestServer(int port)
     {
         super(port, 30, 10);
@@ -71,25 +69,21 @@
     public MongoTestServer(int port, int maxInactivePeriod, int scavengePeriod)
     {
         super(port, maxInactivePeriod, scavengePeriod);
-        _saveInterval = 0;
     }
     
     
     public MongoTestServer(int port, int maxInactivePeriod, int scavengePeriod, boolean saveAllAttributes)
     {
         super(port, maxInactivePeriod, scavengePeriod);
-        _saveAllAttributes = saveAllAttributes;
     }
 
     public SessionIdManager newSessionIdManager(Object config)
     {
         try
         {
-            System.err.println("MongoTestServer:SessionIdManager scavenge: delay:"+ _scavengePeriod + " period:"+_scavengePeriod);
-            MongoSessionIdManager idManager = new TestMongoSessionIdManager(_server);
+            MongoSessionIdManager idManager = new MongoSessionIdManager(_server, getCollection());
             idManager.setWorkerName("w"+(__workers++));
-            idManager.setScavengePeriod(_scavengePeriod);                  
-
+               
             return idManager;
         }
         catch (Exception e)
@@ -104,15 +98,16 @@
         try
         {
             manager = new MongoSessionManager();
+            manager.getSessionDataStore().setGracePeriodSec(_scavengePeriod);
+            StalePeriodStrategy staleStrategy = new StalePeriodStrategy();
+            staleStrategy.setStaleSec(STALE_INTERVAL);
+           ((AbstractSessionStore)manager.getSessionStore()).setStaleStrategy(staleStrategy);
         }
         catch (Exception e)
         {
             throw new RuntimeException(e);
         }
         
-        manager.setSavePeriod(_saveInterval);
-        manager.setStalePeriod(0);
-        manager.setSaveAllAttributes(_saveAllAttributes);
         return manager;
     }
 
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/NewSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/NewSessionTest.java
index 2e6f6a6..4a674cf 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/NewSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/NewSessionTest.java
@@ -20,6 +20,8 @@
 
 import org.eclipse.jetty.server.session.AbstractNewSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -27,6 +29,20 @@
  */
 public class NewSessionTest extends AbstractNewSessionTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
 
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/OrphanedSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/OrphanedSessionTest.java
index 7299cbd..cc8dbf0 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/OrphanedSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/OrphanedSessionTest.java
@@ -20,6 +20,8 @@
 
 import org.eclipse.jetty.server.session.AbstractOrphanedSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -27,6 +29,21 @@
  */
 public class OrphanedSessionTest extends AbstractOrphanedSessionTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
+    
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
        return new MongoTestServer(port,max,scavenge);
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java
index fc080fc..4ccfe6e 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java
@@ -35,7 +35,7 @@
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.client.api.Request;
 import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.junit.Test;
+import org.junit.Ignore;
 
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCollection;
@@ -60,7 +60,7 @@
     
     
     
-    @Test
+    @Ignore
     public void testPurgeInvalidSession() throws Exception
     {
         String contextPath = "";
@@ -76,11 +76,11 @@
 
         MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager();
         MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager();
-        idManager.setPurge(true);
+      /*  idManager.setPurge(true);
         idManager.setPurgeDelay(purgeDelay); 
         idManager.setPurgeInvalidAge(purgeInvalidAge); //purge invalid sessions older than 
         idManager.setPurgeValidAge(purgeValidAge); //purge valid sessions older than
-        
+        */
         
         
         server.start();
@@ -126,7 +126,7 @@
     }
 
 
-    @Test
+    @Ignore
     public void testPurgeInvalidSessionsWithLimit() throws Exception
     {
         String contextPath = "";
@@ -142,11 +142,11 @@
         // disable purging so we can call it manually below
         MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager();
         MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager();
-        idManager.setPurge(false);
+    /*    idManager.setPurge(false);
         idManager.setPurgeLimit(purgeLimit);
         idManager.setPurgeInvalidAge(purgeInvalidAge);
         // don't purge valid sessions
-        idManager.setPurgeValidAge(0);
+        idManager.setPurgeValidAge(0);*/
 
 
         server.start();
@@ -154,7 +154,7 @@
         try
         {
             // cleanup any previous sessions that are invalid so that we are starting fresh
-            idManager.purgeFully();
+         /*   idManager.purgeFully();*/
             long sessionCountAtTestStart = sessionManager.getSessionStoreCount();
 
             HttpClient client = new HttpClient();
@@ -185,7 +185,7 @@
                 assertEquals("Expected to find right number of sessions before purge", sessionCountAtTestStart + (purgeLimit * 2), sessionManager.getSessionStoreCount());
 
                 // run our purge we should still have items in the DB
-                idManager.purge();
+             /*   idManager.purge();*/
                 assertEquals("Expected to find sessions remaining in db after purge run with limit set",
                         sessionCountAtTestStart + purgeLimit, sessionManager.getSessionStoreCount());
             }
@@ -237,9 +237,9 @@
                 //still in db, just marked as invalid
                 dbSession = _sessions.findOne(new BasicDBObject("id", id));       
                 assertNotNull(dbSession);
-                assertTrue(dbSession.containsField(MongoSessionManager.__INVALIDATED));
-                assertTrue(dbSession.containsField(MongoSessionManager.__VALID));
-                assertTrue(dbSession.get(MongoSessionManager.__VALID).equals(false));
+         /*       assertTrue(dbSession.containsField(MongoSessionManager.__INVALIDATED));*/
+                assertTrue(dbSession.containsField(MongoSessionDataStore.__VALID));
+                assertTrue(dbSession.get(MongoSessionDataStore.__VALID).equals(false));
             }
             else if ("test".equals(action))
             {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java
index b8b4700..c770e22 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java
@@ -34,9 +34,8 @@
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.nosql.mongodb.MongoTestServer.TestMongoSessionIdManager;
 import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.junit.Test;
+import org.junit.Ignore;
 
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCollection;
@@ -64,7 +63,7 @@
 
 
 
-    @Test
+    @Ignore
     public void testPurgeValidSession() throws Exception
     {
         String contextPath = "";
@@ -79,11 +78,11 @@
 
         MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager();
         MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager();
-        idManager.setPurge(true);
+    /*    idManager.setPurge(true);
         idManager.setPurgeDelay(purgeDelay); 
 
         idManager.setPurgeValidAge(purgeValidAge); //purge valid sessions older than
-
+*/
 
 
         server.start();
@@ -124,7 +123,7 @@
     }
 
 
-    @Test
+    @Ignore
     public void testPurgeValidSessionWithPurgeLimitSet() throws Exception
     {
         String contextPath = "";
@@ -141,18 +140,18 @@
         MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager();
         MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager();
         // disable purging we will run it manually below
-        idManager.setPurge(false);
+       /* idManager.setPurge(false);
         idManager.setPurgeLimit(purgeLimit);
         idManager.setPurgeDelay(purgeDelay);
         idManager.setPurgeValidAge(purgeValidAge); //purge valid sessions older than
-
+*/
         server.start();
         int port=server.getPort();
 
         try
         {
             // start with no sessions
-            ((TestMongoSessionIdManager)idManager).deleteAll();
+            //((TestMongoSessionIdManager)idManager).deleteAll();
 
             HttpClient client = new HttpClient();
             client.start();
@@ -176,7 +175,7 @@
                 assertEquals("Expected to find right number of sessions before purge", purgeLimit * 2, sessionManager.getSessionStoreCount());
 
                 // run our purge
-                idManager.purge();
+             /*   idManager.purge();*/
 
                 assertEquals("Expected to find sessions remaining in db after purge run with limit set",
                         purgeLimit, sessionManager.getSessionStoreCount());
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ReentrantRequestSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ReentrantRequestSessionTest.java
index 1666c3f..ee839d0 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ReentrantRequestSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ReentrantRequestSessionTest.java
@@ -20,6 +20,8 @@
 
 import org.eclipse.jetty.server.session.AbstractReentrantRequestSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -27,6 +29,21 @@
  */
 public class ReentrantRequestSessionTest extends AbstractReentrantRequestSessionTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
+    
     public AbstractTestServer createServer(int port)
     {
         return new MongoTestServer(port);
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/RemoveSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/RemoveSessionTest.java
index 13ac126..be6cffe 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/RemoveSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/RemoveSessionTest.java
@@ -20,11 +20,27 @@
 
 import org.eclipse.jetty.server.session.AbstractRemoveSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class RemoveSessionTest extends AbstractRemoveSessionTest
 { 
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
         return new MongoTestServer(port,max,scavenge);
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ScatterGunLoadTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ScatterGunLoadTest.java
index 0e5af91..b700d29 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ScatterGunLoadTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ScatterGunLoadTest.java
@@ -20,6 +20,8 @@
 
 import org.eclipse.jetty.server.session.AbstractScatterGunLoadTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
@@ -27,6 +29,20 @@
  */
 public class ScatterGunLoadTest extends AbstractScatterGunLoadTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
 
     public AbstractTestServer createServer(int port)
     {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ServerCrossContextSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ServerCrossContextSessionTest.java
index 7504e07..956134a 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ServerCrossContextSessionTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/ServerCrossContextSessionTest.java
@@ -20,11 +20,28 @@
 
 import org.eclipse.jetty.server.session.AbstractServerCrossContextSessionTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 
 public class ServerCrossContextSessionTest extends AbstractServerCrossContextSessionTest
 {
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
+    
     public AbstractTestServer createServer(int port)
     {
         return new MongoTestServer(port);
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java
index 54df88f..1fd9de3 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java
@@ -20,11 +20,27 @@
 
 import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class SessionExpiryTest extends AbstractSessionExpiryTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionInvalidateAndCreateTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionInvalidateAndCreateTest.java
index b40f4e5..5002c67 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionInvalidateAndCreateTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionInvalidateAndCreateTest.java
@@ -20,11 +20,27 @@
 
 import org.eclipse.jetty.server.session.AbstractSessionInvalidateAndCreateTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class SessionInvalidateAndCreateTest extends AbstractSessionInvalidateAndCreateTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionMigrationTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionMigrationTest.java
index 04014b5..e7e2642 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionMigrationTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionMigrationTest.java
@@ -20,11 +20,27 @@
 
 import org.eclipse.jetty.server.session.AbstractSessionMigrationTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class SessionMigrationTest extends AbstractSessionMigrationTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     @Override
     public AbstractTestServer createServer(int port)
     {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java
index d0da35d..4bf75fb 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java
@@ -20,11 +20,27 @@
 
 import org.eclipse.jetty.server.session.AbstractSessionRenewTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class SessionRenewTest extends AbstractSessionRenewTest
 {
 
+    
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
+    
     @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionSavingValueTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionSavingValueTest.java
index 87804ee..6b02b95 100644
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionSavingValueTest.java
+++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionSavingValueTest.java
@@ -18,227 +18,42 @@
 
 package org.eclipse.jetty.nosql.mongodb;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.lang.management.ManagementFactory;
-import java.net.MalformedURLException;
-
-import javax.management.remote.JMXServiceURL;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.jmx.ConnectorServer;
-import org.eclipse.jetty.jmx.MBeanContainer;
-import org.eclipse.jetty.nosql.NoSqlSession;
 import org.eclipse.jetty.server.session.AbstractSessionValueSavingTest;
 import org.eclipse.jetty.server.session.AbstractTestServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class SessionSavingValueTest extends AbstractSessionValueSavingTest
 {
 
     
+    @BeforeClass
+    public static void beforeClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+        MongoTestServer.createCollection();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception
+    {
+        MongoTestServer.dropCollection();
+    }
     
+    @Override
     public AbstractTestServer createServer(int port, int max, int scavenge)
     {
-        ConnectorServer srv = null;
-        try
-        {
-            srv = new ConnectorServer(
-                    new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:0/jettytest"),
-                    "org.eclipse.jetty:name=rmiconnectorserver");
-            srv.start();
-            
-            MongoTestServer server = new MongoTestServer(port,max,scavenge,true);
-
-            MBeanContainer mbean = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
-           
-            //server.getServer().getContainer().addEventListener(mbean);
-            server.getServer().addBean(mbean);
-
-            //mbean.start();
-                    
-            return server;
-
-        }
-        catch (MalformedURLException e)
-        {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        catch (Exception e)
-        {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        
-        return null;
+        return new MongoTestServer(port, max, scavenge);
     }
 
     @Test
-    //@Ignore ("requires mongodb server")
     public void testSessionValueSaving() throws Exception
     {
-        String contextPath = "";
-        String servletMapping = "/server";
-        int maxInactivePeriod = 10000;
-        int scavengePeriod = 20000;
-        AbstractTestServer server1 = createServer(0,maxInactivePeriod,scavengePeriod);
-        server1.addContext(contextPath).addServlet(TestServlet.class,servletMapping);
-        server1.start();
-        int port1 = server1.getPort();
-        try
-        {
-
-            HttpClient client = new HttpClient();
-            client.start();
-            try
-            {
-                String[] sessionTestValue = new String[]
-                { "0", "null" };
-
-                // Perform one request to server1 to create a session
-                ContentResponse response = client.GET("http://localhost:" + port1 + contextPath + servletMapping + "?action=init");
-      
-                assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-
-                String[] sessionTestResponse = response.getContentAsString().split("/");
-                assertTrue(Long.parseLong(sessionTestValue[0]) < Long.parseLong(sessionTestResponse[0]));
-
-                sessionTestValue = sessionTestResponse;
-
-                String sessionCookie = response.getHeaders().get("Set-Cookie");
-                assertTrue(sessionCookie != null);
-                // Mangle the cookie, replacing Path with $Path, etc.
-                sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=","$1\\$Path=");
-
-                // Perform some request to server2 using the session cookie from the previous request
-                // This should migrate the session from server1 to server2, and leave server1's
-                // session in a very stale state, while server2 has a very fresh session.
-                // We want to test that optimizations done to the saving of the shared lastAccessTime
-                // do not break the correct working
-                int requestInterval = 500;
-
-                for (int i = 0; i < 10; ++i)
-                {
-                    Request request2 = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping);
-                    request2.header("Cookie",sessionCookie);
-                    ContentResponse response2 = request2.send();
-         
-                    assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
-
-                    sessionTestResponse = response2.getContentAsString().split("/");
-
-                    assertTrue(Long.parseLong(sessionTestValue[0]) < Long.parseLong(sessionTestResponse[0]));
-                    assertTrue(Long.parseLong(sessionTestValue[1]) < Long.parseLong(sessionTestResponse[1]));
-
-                    sessionTestValue = sessionTestResponse;
-
-                    String setCookie = response2.getHeaders().get("Set-Cookie");
-                    if (setCookie != null)
-                        sessionCookie = setCookie.replaceFirst("(\\W)(P|p)ath=","$1\\$Path=");
-
-                    Thread.sleep(requestInterval);
-                }
-
- //               Thread.sleep(320000);
-            }
-            finally
-            {
-                client.stop();
-            }
-        }
-        finally
-        {
-            server1.stop();
-        }
+        super.testSessionValueSaving();
     }
 
-    public static class TestServlet extends HttpServlet
-    {
-        @Override
-        protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
-        {
-            String action = request.getParameter("action");
-            if ("init".equals(action))
-            {
-                NoSqlSession session = (NoSqlSession)request.getSession(true);
-                session.setAttribute("test",System.currentTimeMillis());
-                session.setAttribute("objectTest", new Pojo("foo","bar"));
-                
-                sendResult(session,httpServletResponse.getWriter());
-                
-            }
-            else
-            {
-                NoSqlSession session = (NoSqlSession)request.getSession(false);
-                if (session != null)
-                {
-                    long value = System.currentTimeMillis();
-                    session.setAttribute("test",value);
-
-                }
-
-                sendResult(session,httpServletResponse.getWriter());
-
-                Pojo p = (Pojo)session.getAttribute("objectTest");
-                
-                //System.out.println(p.getName() + " / " + p.getValue() );
-            }
-
-        }
-
-        private void sendResult(NoSqlSession session, PrintWriter writer)
-        {
-            if (session != null)
-            {
-                if (session.getVersion() == null)
-                {
-                    writer.print(session.getAttribute("test") + "/-1");
-                }
-                else
-                {
-                    writer.print(session.getAttribute("test") + "/" + session.getVersion());
-                }
-            }
-            else
-            {
-                writer.print("0/-1");
-            }
-        }
-        
-        public class Pojo implements Serializable
-        {
-            private String _name;
-            private String _value;
-            
-            public Pojo( String name, String value )
-            {
-                _name = name;
-                _value = value;
-            }
-            
-            public String getName()
-            {
-                return _name;
-            }
-            
-            public String getValue()
-            {
-                return _value;
-            }
-        }
-        
-    }
-
+    
+  
  
 }
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/StopSessionManagerDeleteSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/StopSessionManagerDeleteSessionTest.java
deleted file mode 100644
index 9bd383d..0000000
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/StopSessionManagerDeleteSessionTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.nosql.mongodb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.junit.Test;
-
-import com.mongodb.BasicDBObject;
-import com.mongodb.DBCollection;
-import com.mongodb.DBObject;
-import com.mongodb.Mongo;
-import com.mongodb.MongoException;
-
-public class StopSessionManagerDeleteSessionTest
-{
-    public MongoTestServer createServer(int port, int max, int scavenge)
-    {
-        MongoTestServer server =  new MongoTestServer(port,max,scavenge);
-       
-        return server;
-    }
-    
-    /**
-     * @throws Exception
-     */
-    @Test
-    public void testStopSessionManagerDeleteSession() throws Exception
-    {
-        String contextPath = "";
-        String servletMapping = "/server";
-        
-        MongoTestServer server = createServer(0, 1, 0);
-        ServletContextHandler context = server.addContext(contextPath);
-        ServletHolder holder = new ServletHolder();
-        TestServlet servlet = new TestServlet();
-        holder.setServlet(servlet);
-        
-        context.addServlet(holder, servletMapping);
-        
-        MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager();
-        sessionManager.setPreserveOnStop(false);
-        MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager();
-        idManager.setPurge(true);
-
-        
-        server.start();
-        int port=server.getPort();
-        try
-        {
-            HttpClient client = new HttpClient();
-            client.start();
-            try
-            {
-                //Create a session
-                ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create");
-                assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-                String sessionCookie = response.getHeaders().get("Set-Cookie");
-                assertTrue(sessionCookie != null);
-                // Mangle the cookie, replacing Path with $Path, etc.
-                sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
-
-                //stop the session manager
-                sessionManager.stop();
-                
-                //check the database to see that the session has been marked invalid
-                servlet.checkSessionInDB(false);
-                
-            }
-            finally
-            {
-                client.stop();
-            }
-        }
-        finally
-        {
-            server.stop();
-        }
-    }
-    
-    
-    public static class TestServlet extends HttpServlet
-    {
-        DBCollection _sessions;
-        String _id;
-
-        public TestServlet() throws UnknownHostException, MongoException
-        {
-            super();            
-            _sessions = new Mongo().getDB("HttpSessions").getCollection("sessions");
-        }
-
-        public void checkSessionInDB (boolean expectedValid)
-        {
-            DBObject dbSession = _sessions.findOne(new BasicDBObject("id", _id));
-            assertTrue(dbSession != null);
-            assertEquals(expectedValid, dbSession.get("valid"));
-            if (!expectedValid)
-                assertNotNull(dbSession.get(MongoSessionManager.__INVALIDATED));
-        }
-
-        public String getId()
-        {
-            return _id;
-        }
-        
-        @Override
-        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
-        {
-            String action = request.getParameter("action");
-            if ("create".equals(action))
-            {
-                HttpSession session = request.getSession(true);
-                session.setAttribute("foo", "bar");
-                assertTrue(session.isNew());
-                _id = session.getId();
-            }
-            else if ("test".equals(action))
-            {
-                String id = request.getRequestedSessionId();
-                assertNotNull(id);
-                id = id.substring(0, id.indexOf("."));
-  
-                HttpSession existingSession = request.getSession(false);
-                assertTrue(existingSession == null);
-                
-                //not in db any more
-                DBObject dbSession = _sessions.findOne(new BasicDBObject("id", id));
-                assertTrue(dbSession == null);
-            }
-        }
-    }
-}
diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/StopSessionManagerPreserveSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/StopSessionManagerPreserveSessionTest.java
deleted file mode 100644
index 59c831e..0000000
--- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/StopSessionManagerPreserveSessionTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-
-package org.eclipse.jetty.nosql.mongodb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.net.UnknownHostException;
-
-import org.eclipse.jetty.server.session.AbstractStopSessionManagerPreserveSessionTest;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.mongodb.BasicDBObject;
-import com.mongodb.DBCollection;
-import com.mongodb.DBObject;
-import com.mongodb.Mongo;
-import com.mongodb.MongoException;
-
-/**
- * StopSessionManagerPreserveSessionTest
- *
- *
- */
-public class StopSessionManagerPreserveSessionTest extends AbstractStopSessionManagerPreserveSessionTest
-{
-    DBCollection _sessions;
-    
-    @Before
-    public void setUp() throws UnknownHostException, MongoException
-    {
-        _sessions = new Mongo().getDB("HttpSessions").getCollection("sessions");
-    }
-    
-   
-    
-    public MongoTestServer createServer(int port)
-    {
-        MongoTestServer server =  new MongoTestServer(port); 
-        server.getServer().setStopTimeout(0);
-        return server;
-    }
-    
-    
-
-    @Override
-    public void checkSessionPersisted(boolean expected)
-    {
-        DBObject dbSession = _sessions.findOne(new BasicDBObject("id", _id));
-
-        if (expected)
-        {
-            assertTrue(dbSession != null);
-            assertEquals(expected, dbSession.get("valid"));
-        }
-        else
-        {
-            assertTrue(dbSession==null);
-        }
-    }
-
-
-    @Override
-    public void configureSessionManagement(ServletContextHandler context)
-    {
-        ((MongoSessionManager)context.getSessionHandler().getSessionManager()).setPreserveOnStop(true);
-    }
-
-    /**
-     * @throws Exception
-     */
-    @Test
-    public void testStopSessionManagerPreserveSession() throws Exception
-    {
-        super.testStopSessionManagerPreserveSession();
-    }
-
-
-
-}
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractForwardedSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractForwardedSessionTest.java
index e5e6c6b..743ca49 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractForwardedSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractForwardedSessionTest.java
@@ -126,6 +126,7 @@
    
             HttpSession sess = request.getSession(false);
             assertNotNull(sess);
+            assertNotNull(sess.getAttribute("servlet3"));
             sess.setAttribute("servlet1", "servlet1");
         }
     }
@@ -144,6 +145,7 @@
             //the session should exist after the forward
             HttpSession sess = request.getSession(false);
             assertNotNull(sess);
+            assertNotNull(sess.getAttribute("servlet3"));
         }
     }
 
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java
index 3d1c970..d9f7b6f 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractImmortalSessionTest.java
@@ -33,6 +33,7 @@
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.junit.Test;
 
 
@@ -51,7 +52,8 @@
         int scavengePeriod = 2;
         //turn off session expiry by setting maxInactiveInterval to -1
         AbstractTestServer server = createServer(0, -1, scavengePeriod);
-        server.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
+        ServletContextHandler context = server.addContext(contextPath);
+        context.addServlet(TestServlet.class, servletMapping);
 
         try
         {
@@ -74,7 +76,7 @@
 
                 // Let's wait for the scavenger to run, waiting 2.5 times the scavenger period
                 Thread.sleep(scavengePeriod * 2500L);
-
+                
                 // Be sure the session is still there
                 Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=get");
                 request.header("Cookie", sessionCookie);
@@ -82,6 +84,8 @@
                 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
                 resp = response.getContentAsString();
                 assertEquals(String.valueOf(value),resp.trim());
+                
+                assertEquals(1, ((org.eclipse.jetty.server.session.SessionManager)context.getSessionHandler().getSessionManager()).getSessionsCreated());
             }
             finally
             {
@@ -110,7 +114,7 @@
             }
             else if ("get".equals(action))
             {
-                HttpSession session = request.getSession(false);
+                HttpSession session = request.getSession(false);               
                 if (session!=null)
                     result = (String)session.getAttribute("value");
             }
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java
index de345ef..83e4d1d 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractInvalidationSessionTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.IOException;
 
@@ -32,7 +33,6 @@
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.util.thread.QueuedThreadPool;
 import org.junit.Test;
 
@@ -52,20 +52,16 @@
         String contextPath = "";
         String servletMapping = "/server";
         AbstractTestServer server1 = createServer(0);
-        ServletContextHandler context1 = server1.addContext(contextPath);
-        context1.addServlet(TestServlet.class, servletMapping);
+        server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
 
-        AbstractSessionManager m1 = (AbstractSessionManager) context1.getSessionHandler().getSessionManager();
 
         try
         {
             server1.start();
             int port1 = server1.getPort();
             AbstractTestServer server2 = createServer(0);
-            ServletContextHandler context2 = server2.addContext(contextPath);
-            context2.addServlet(TestServlet.class, servletMapping);
-            AbstractSessionManager m2 = (AbstractSessionManager) context2.getSessionHandler().getSessionManager();
-            
+            server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
+
             try
             {
                 server2.start();
@@ -74,6 +70,7 @@
                 QueuedThreadPool executor = new QueuedThreadPool();
                 client.setExecutor(executor);
                 client.start();
+                
                 try
                 {
                     String[] urls = new String[2];
@@ -86,33 +83,21 @@
                     assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
                     String sessionCookie = response1.getHeaders().get("Set-Cookie");
                     assertTrue(sessionCookie != null);
-                    assertEquals(1, m1.getSessions());
-                    assertEquals(1, m1.getSessionsMax());
-                    assertEquals(1, m1.getSessionsTotal());
-                    
                     // Mangle the cookie, replacing Path with $Path, etc.
                     sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
-                    
-                    
+
                     // Be sure the session is also present in node2
                     Request request2 = client.newRequest(urls[1] + "?action=increment");
                     request2.header("Cookie", sessionCookie);
                     ContentResponse response2 = request2.send();
                     assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
-                    assertEquals(1, m2.getSessions());
-                    assertEquals(1, m2.getSessionsMax());
-                    assertEquals(1, m2.getSessionsTotal());
-                    
 
                     // Invalidate on node1
                     Request request1 = client.newRequest(urls[0] + "?action=invalidate");
                     request1.header("Cookie", sessionCookie);
                     response1 = request1.send();
                     assertEquals(HttpServletResponse.SC_OK, response1.getStatus());
-                    assertEquals(0, m1.getSessions());
-                    assertEquals(1, m1.getSessionsMax());
-                    assertEquals(1, m1.getSessionsTotal());
-                   
+
                     pause();
 
                     // Be sure on node2 we don't see the session anymore
@@ -120,9 +105,6 @@
                     request2.header("Cookie", sessionCookie);
                     response2 = request2.send();
                     assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
-                    assertEquals(0, m2.getSessions());
-                    assertEquals(1, m2.getSessionsMax());
-                    assertEquals(1, m2.getSessionsTotal());
                 }
                 finally
                 {
@@ -161,6 +143,18 @@
             {
                 HttpSession session = request.getSession(false);
                 session.invalidate();
+                
+                try
+                {
+                    session.invalidate();
+                    fail("Session should be invalid");
+                    
+                }
+                catch (IllegalStateException e)
+                {
+                    //expected
+                }
+                
             }
             else if ("test".equals(action))
             {
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java
index 847e800..d684bef 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLastAccessTimeTest.java
@@ -24,6 +24,8 @@
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -51,7 +53,10 @@
  */
 public abstract class AbstractLastAccessTimeTest
 {
+    
     public abstract AbstractTestServer createServer(int port, int max, int scavenge);
+ 
+   
 
     @Test
     public void testLastAccessTime() throws Exception
@@ -67,7 +72,7 @@
         TestSessionListener listener1 = new TestSessionListener();
         context.getSessionHandler().addEventListener(listener1);
         context.addServlet(holder1, servletMapping);
-        AbstractSessionManager m1 = (AbstractSessionManager)context.getSessionHandler().getSessionManager();
+        SessionManager m1 = (SessionManager)context.getSessionHandler().getSessionManager();
         
 
         try
@@ -77,7 +82,7 @@
             AbstractTestServer server2 = createServer(0, maxInactivePeriod, scavengePeriod);
             ServletContextHandler context2 = server2.addContext(contextPath);
             context2.addServlet(TestServlet.class, servletMapping);
-            AbstractSessionManager m2 = (AbstractSessionManager)context2.getSessionHandler().getSessionManager();
+            SessionManager m2 = (SessionManager)context2.getSessionHandler().getSessionManager();
 
             try
             {
@@ -93,9 +98,9 @@
                     assertEquals("test", response1.getContentAsString());
                     String sessionCookie = response1.getHeaders().get("Set-Cookie");
                     assertTrue( sessionCookie != null );
-                    assertEquals(1, m1.getSessions());
-                    assertEquals(1, m1.getSessionsMax());
-                    assertEquals(1, m1.getSessionsTotal());
+                    assertEquals(1, ((MemorySessionStore)m1.getSessionStore()).getSessions());
+                    assertEquals(1, ((MemorySessionStore)m1.getSessionStore()).getSessionsMax());
+                    assertEquals(1, ((MemorySessionStore)m1.getSessionStore()).getSessionsTotal());
                     // Mangle the cookie, replacing Path with $Path, etc.
                     sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");        
                     
@@ -120,12 +125,13 @@
                         Thread.sleep(requestInterval);
                         assertSessionCounts(1,1,1, m2);
                     }
+                    
                     // At this point, session1 should be eligible for expiration.
                     // Let's wait for the scavenger to run, waiting 2.5 times the scavenger period
                     Thread.sleep(scavengePeriod * 2500L);
 
                     //check that the session was not scavenged over on server1 by ensuring that the SessionListener destroy method wasn't called
-                    assertFalse(listener1.destroyed);
+                    assertFalse(listener1._destroys.contains(AbstractTestServer.extractSessionId(sessionCookie)));
                     assertAfterScavenge(m1);
                 }
                 finally
@@ -144,38 +150,38 @@
         }
     }
     
-    public void assertAfterSessionCreated (AbstractSessionManager m)
+    public void assertAfterSessionCreated (SessionManager m)
     {
         assertSessionCounts(1, 1, 1, m);
     }
     
-    public void assertAfterScavenge (AbstractSessionManager manager)
+    public void assertAfterScavenge (SessionManager manager)
     {
         assertSessionCounts(1,1,1, manager);
     }
     
-    public void assertSessionCounts (int current, int max, int total, AbstractSessionManager manager)
+    public void assertSessionCounts (int current, int max, int total, SessionManager manager)
     {
-        assertEquals(current, manager.getSessions());
-        assertEquals(max, manager.getSessionsMax());
-        assertEquals(total, manager.getSessionsTotal());
+        assertEquals(current, ((MemorySessionStore)manager.getSessionStore()).getSessions());
+        assertEquals(max, ((MemorySessionStore)manager.getSessionStore()).getSessionsMax());
+        assertEquals(total, ((MemorySessionStore)manager.getSessionStore()).getSessionsTotal());
     }
 
     public static class TestSessionListener implements HttpSessionListener
     {
-        public boolean destroyed = false;
-        public boolean created = false;
+        public Set<String> _creates = new HashSet<String>();
+        public Set<String> _destroys = new HashSet<String>();
 
         @Override
         public void sessionDestroyed(HttpSessionEvent se)
         {
-           destroyed = true;
+           _destroys.add(se.getSession().getId());
         }
 
         @Override
         public void sessionCreated(HttpSessionEvent se)
         {
-            created = true;
+            _creates.add(se.getSession().getId());
         }
     }
 
@@ -183,7 +189,10 @@
 
     public static class TestServlet extends HttpServlet
     {
-
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
 
         @Override
         protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
@@ -212,14 +221,14 @@
 
         private void sendResult(HttpSession session, PrintWriter writer)
         {
-                if (session != null)
-                {
-                        writer.print(session.getAttribute("test"));
-                }
-                else
-                {
-                        writer.print("null");
-                }
+            if (session != null)
+            {
+                writer.print(session.getAttribute("test"));
+            }
+            else
+            {
+                writer.print("null");
+            }
         }
     }
 }
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java
index 09a5adf..38848d8 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractLocalSessionScavengingTest.java
@@ -33,6 +33,7 @@
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.junit.Test;
 
 /**
@@ -62,14 +63,16 @@
         int inactivePeriod = 1;
         int scavengePeriod = 2;
         AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
-        server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
+        ServletContextHandler context1 = server1.addContext(contextPath);
+        context1.addServlet(TestServlet.class, servletMapping);
 
         try
         {
             server1.start();
             int port1 = server1.getPort();
             AbstractTestServer server2 = createServer(0, inactivePeriod, scavengePeriod * 3);
-            server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
+            ServletContextHandler context2 = server2.addContext(contextPath);
+            context2.addServlet(TestServlet.class, servletMapping);
 
             try
             {
@@ -90,28 +93,33 @@
                     assertTrue(sessionCookie != null);
                     // Mangle the cookie, replacing Path with $Path, etc.
                     sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
+                    org.eclipse.jetty.server.session.SessionManager m1 = (org.eclipse.jetty.server.session.SessionManager)context1.getSessionHandler().getSessionManager();
+                    assertEquals(1,  m1.getSessionsCreated());
 
                     // Be sure the session is also present in node2
                     org.eclipse.jetty.client.api.Request request = client.newRequest(urls[1] + "?action=test");
                     request.header("Cookie", sessionCookie);
                     ContentResponse response2 = request.send();
                     assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
-
+                    org.eclipse.jetty.server.session.SessionManager m2 = (org.eclipse.jetty.server.session.SessionManager)context2.getSessionHandler().getSessionManager();
 
                     // Wait for the scavenger to run on node1, waiting 2.5 times the scavenger period
                     pause(scavengePeriod);
 
+                    assertEquals(1,  m1.getSessionsCreated());
+
                     // Check that node1 does not have any local session cached
                     request = client.newRequest(urls[0] + "?action=check");
                     request.header("Cookie", sessionCookie);
                     response1 = request.send();
                     assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
-
+                    
+                    assertEquals(1,  m1.getSessionsCreated());
 
                     // Wait for the scavenger to run on node2, waiting 2 times the scavenger period
                     // This ensures that the scavenger on node2 runs at least once.
                     pause(scavengePeriod);
-
+                    
                     // Check that node2 does not have any local session cached
                     request = client.newRequest(urls[1] + "?action=check");
                     request.header("Cookie", sessionCookie);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractRemoveSessionTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractRemoveSessionTest.java
index bb126f6..910ed19 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractRemoveSessionTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractRemoveSessionTest.java
@@ -61,7 +61,7 @@
         context.addServlet(TestServlet.class, servletMapping);
         TestEventListener testListener = new TestEventListener();
         context.getSessionHandler().addEventListener(testListener);
-        AbstractSessionManager m = (AbstractSessionManager)context.getSessionHandler().getSessionManager();
+        SessionManager m = (SessionManager) context.getSessionHandler().getSessionManager();
         try
         {
             server.start();
@@ -79,9 +79,9 @@
                 sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
                 //ensure sessionCreated listener is called
                 assertTrue (testListener.isCreated());
-                assertEquals(1, m.getSessions());
-                assertEquals(1, m.getSessionsMax());
-                assertEquals(1, m.getSessionsTotal());
+                assertEquals(1, m.getSessionsCreated());
+                assertEquals(1, ((MemorySessionStore)m.getSessionStore()).getSessionsMax());
+                assertEquals(1, ((MemorySessionStore)m.getSessionStore()).getSessionsTotal());
                 
                 //now delete the session
                 Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=delete");
@@ -90,18 +90,18 @@
                 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
                 //ensure sessionDestroyed listener is called
                 assertTrue(testListener.isDestroyed());
-                assertEquals(0, m.getSessions());
-                assertEquals(1, m.getSessionsMax());
-                assertEquals(1, m.getSessionsTotal());
+                assertEquals(0, ((MemorySessionStore)m.getSessionStore()).getSessions());
+                assertEquals(1, ((MemorySessionStore)m.getSessionStore()).getSessionsMax());
+                assertEquals(1, ((MemorySessionStore)m.getSessionStore()).getSessionsTotal());
 
                 // The session is not there anymore, even if we present an old cookie
                 request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=check");
                 request.header("Cookie", sessionCookie);
                 response = request.send();
                 assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-                assertEquals(0, m.getSessions());
-                assertEquals(1, m.getSessionsMax());
-                assertEquals(1, m.getSessionsTotal());
+                assertEquals(0, ((MemorySessionStore)m.getSessionStore()).getSessions());
+                assertEquals(1,  ((MemorySessionStore)m.getSessionStore()).getSessionsMax());
+                assertEquals(1, ((MemorySessionStore)m.getSessionStore()).getSessionsTotal());
             }
             finally
             {
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java
index 0c221a2..0dce5f4 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionExpiryTest.java
@@ -181,7 +181,7 @@
             
             port1 = server1.getPort();
             url = "http://localhost:" + port1 + contextPath + servletMapping;
-
+            
             //make another request, the session should have expired
             Request request = client.newRequest(url + "?action=test");
             request.getHeaders().add("Cookie", sessionCookie);
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionInvalidateAndCreateTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionInvalidateAndCreateTest.java
index 40df64f..c749c47 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionInvalidateAndCreateTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionInvalidateAndCreateTest.java
@@ -123,13 +123,12 @@
                 // Mangle the cookie, replacing Path with $Path, etc.
                 sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
 
-
                 // Make a request which will invalidate the existing session and create a new one
                 Request request2 = client.newRequest(url + "?action=test");
                 request2.header("Cookie", sessionCookie);
                 ContentResponse response2 = request2.send();
                 assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
-
+         
                 // Wait for the scavenger to run, waiting 3 times the scavenger period
                 pause(scavengePeriod);
 
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java
index 6ef67d6..e9e0b2c 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java
@@ -79,6 +79,7 @@
             Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=renew");
             request.header("Cookie", sessionCookie);
             ContentResponse renewResponse = request.send();
+
             assertEquals(HttpServletResponse.SC_OK,renewResponse.getStatus());
             String renewSessionCookie = renewResponse.getHeaders().get("Set-Cookie");
             assertNotNull(renewSessionCookie);
@@ -131,8 +132,7 @@
                 assertTrue(beforeSession != null);
                 String beforeSessionId = beforeSession.getId();
 
-
-                ((AbstractSession)beforeSession).renewId(request);
+                ((Session)beforeSession).renewId(request);
 
                 HttpSession afterSession = request.getSession(false);
                 assertTrue(afterSession != null);
@@ -141,18 +141,18 @@
                 assertTrue(beforeSession==afterSession);
                 assertFalse(beforeSessionId.equals(afterSessionId));
 
-                AbstractSessionManager sessionManager = (AbstractSessionManager)((AbstractSession)afterSession).getSessionManager();
+                SessionManager sessionManager = ((Session)afterSession).getSessionManager();
                 AbstractSessionIdManager sessionIdManager = (AbstractSessionIdManager)sessionManager.getSessionIdManager();
 
-                assertTrue(sessionIdManager.idInUse(afterSessionId));
-                assertFalse(sessionIdManager.idInUse(beforeSessionId));
+                assertTrue(sessionIdManager.isIdInUse(afterSessionId));
+                assertFalse(sessionIdManager.isIdInUse(beforeSessionId));
 
                 HttpSession session = sessionManager.getSession(afterSessionId);
                 assertNotNull(session);
                 session = sessionManager.getSession(beforeSessionId);
                 assertNull(session);
 
-                if (((AbstractSession)afterSession).isIdChanged())
+                if (((Session)afterSession).isIdChanged())
                 {
                     ((org.eclipse.jetty.server.Response)response).addCookie(sessionManager.getSessionCookie(afterSession, request.getContextPath(), request.isSecure()));
                 }
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionValueSavingTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionValueSavingTest.java
index 8b0851b..f2c8ebb 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionValueSavingTest.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionValueSavingTest.java
@@ -77,9 +77,6 @@
                     // Mangle the cookie, replacing Path with $Path, etc.
                     sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
 
-                    // Perform some request to server2 using the session cookie from the previous request
-                    // This should migrate the session from server1 to server2, and leave server1's
-                    // session in a very stale state, while server2 has a very fresh session.
                     // We want to test that optimizations done to the saving of the shared lastAccessTime
                     // do not break the correct working
                     int requestInterval = 500;
@@ -130,13 +127,10 @@
             else
             {
                 HttpSession session = request.getSession(false);
-                System.out.println("not init call " + session);
                 if (session!=null)
                 {
-                        long value = System.currentTimeMillis();
-                        System.out.println("Setting test to : " + value);
+                    long value = System.currentTimeMillis();
                     session.setAttribute("test", value);
-
                 }
 
                 sendResult(session, httpServletResponse.getWriter());
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java
index 789f6b2..b98bd16 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java
@@ -42,6 +42,7 @@
     protected final int _scavengePeriod;
     protected final ContextHandlerCollection _contexts;
     protected SessionIdManager _sessionIdManager;
+    private SessionScavenger _scavenger;
 
   
     
@@ -81,6 +82,10 @@
         _contexts = new ContextHandlerCollection();
         _sessionIdManager = newSessionIdManager(sessionIdMgrConfig);
         _server.setSessionIdManager(_sessionIdManager);
+        ((AbstractSessionIdManager) _sessionIdManager).setServer(_server);
+        _scavenger = new SessionScavenger();
+        _scavenger.setScavengeIntervalSec(scavengePeriod);
+        ((AbstractSessionIdManager)_sessionIdManager).setSessionScavenger(_scavenger);
     }
     
     
diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java
index b6675a2..c8e075e 100644
--- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java
+++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/WebAppObjectInSessionServlet.java
@@ -62,7 +62,6 @@
             {
                 HttpSession session = request.getSession(false);
                 Object staticAttribute = session.getAttribute("staticAttribute");
-                System.err.println("staticAttribute="+staticAttribute);
                 Assert.assertTrue(staticAttribute instanceof TestSharedStatic);
                 
 //                Object objectAttribute = session.getAttribute("objectAttribute");
diff --git a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java
index a1d0f6b..3818694 100644
--- a/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java
+++ b/tests/test-webapps/test-jetty-webapp/src/test/java/org/eclipse/jetty/TestServer.java
@@ -44,7 +44,7 @@
 import org.eclipse.jetty.server.handler.HandlerWrapper;
 import org.eclipse.jetty.server.handler.RequestLogHandler;
 import org.eclipse.jetty.server.handler.ResourceHandler;
-import org.eclipse.jetty.server.session.HashSessionManager;
+import org.eclipse.jetty.server.session.FileSessionManager;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 import org.eclipse.jetty.util.log.StdErrLog;
@@ -131,8 +131,8 @@
             sessiondir.delete();
         sessiondir.mkdir();
         sessiondir.deleteOnExit();
-        ((HashSessionManager)webapp.getSessionHandler().getSessionManager()).setStoreDirectory(sessiondir);
-        ((HashSessionManager)webapp.getSessionHandler().getSessionManager()).setSavePeriod(10);
+        ((FileSessionManager)webapp.getSessionHandler().getSessionManager()).getSessionDataStore().setStoreDir(sessiondir);
+        //((HashSessionManager)webapp.getSessionHandler().getSessionManager()).setSavePeriod(10);
 
         contexts.addHandler(webapp);
 
