changeset 809:09d518d313b7

remove SessionManager
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 08 Sep 2016 16:38:30 -0600
parents b3176fd168bf
children 022ff91bde60
files src/luan/modules/http/Server.luan src/org/eclipse/jetty/server/Request.java src/org/eclipse/jetty/server/Response.java src/org/eclipse/jetty/server/SessionManager.java src/org/eclipse/jetty/server/session/AbstractSession.java src/org/eclipse/jetty/server/session/AbstractSessionIdManager.java src/org/eclipse/jetty/server/session/AbstractSessionManager.java src/org/eclipse/jetty/server/session/HashSessionIdManager.java src/org/eclipse/jetty/server/session/HashSessionManager.java src/org/eclipse/jetty/server/session/HashedSession.java src/org/eclipse/jetty/server/session/JDBCSessionIdManager.java src/org/eclipse/jetty/server/session/JDBCSessionManager.java src/org/eclipse/jetty/server/session/SessionHandler.java
diffstat 13 files changed, 1845 insertions(+), 7763 deletions(-) [+]
line wrap: on
line diff
diff -r b3176fd168bf -r 09d518d313b7 src/luan/modules/http/Server.luan
--- a/src/luan/modules/http/Server.luan	Thu Sep 08 16:13:27 2016 -0600
+++ b/src/luan/modules/http/Server.luan	Thu Sep 08 16:38:30 2016 -0600
@@ -23,7 +23,6 @@
 local ContextHandler = require "java:org.eclipse.jetty.server.handler.ContextHandler"
 local GzipHandler = require "java:org.eclipse.jetty.server.handler.GzipHandler"
 local HandlerWrapper = require "java:org.eclipse.jetty.server.handler.HandlerWrapper"
-local SessionHandler = require "java:org.eclipse.jetty.server.session.SessionHandler"
 local AuthenticationHandler = require "java:luan.modules.http.AuthenticationHandler"
 local LuanHandler = require "java:luan.modules.http.LuanHandler"
 local NotFound = require "java:luan.modules.http.NotFound"
@@ -74,7 +73,7 @@
 end
 
 local hc = HandlerCollection.new()
-hc.setHandlers { SessionHandler.new(), M.handler_wrapper, DefaultHandler.new(), M.log_handler }
+hc.setHandlers { M.handler_wrapper, DefaultHandler.new(), M.log_handler }
 
 
 function M.init(dir)
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/Request.java
--- a/src/org/eclipse/jetty/server/Request.java	Thu Sep 08 16:13:27 2016 -0600
+++ b/src/org/eclipse/jetty/server/Request.java	Thu Sep 08 16:38:30 2016 -0600
@@ -127,2078 +127,2034 @@
  */
 public class Request implements HttpServletRequest
 {
-    public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig";
-    public static final String __MULTIPART_INPUT_STREAM = "org.eclipse.multiPartInputStream";
-    public static final String __MULTIPART_CONTEXT = "org.eclipse.multiPartContext";
-    private static final Logger LOG = Log.getLogger(Request.class);
+	public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig";
+	public static final String __MULTIPART_INPUT_STREAM = "org.eclipse.multiPartInputStream";
+	public static final String __MULTIPART_CONTEXT = "org.eclipse.multiPartContext";
+	private static final Logger LOG = Log.getLogger(Request.class);
 
-    private static final String __ASYNC_FWD = "org.eclipse.asyncfwd";
-    private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault());
-    private static final int __NONE = 0, _STREAM = 1, __READER = 2;
+	private static final String __ASYNC_FWD = "org.eclipse.asyncfwd";
+	private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault());
+	private static final int __NONE = 0, _STREAM = 1, __READER = 2;
 
-    public static class MultiPartCleanerListener implements ServletRequestListener
-    {
+	public static class MultiPartCleanerListener implements ServletRequestListener
+	{
 
-        @Override
-        public void requestDestroyed(ServletRequestEvent sre)
-        {
-            //Clean up any tmp files created by MultiPartInputStream
-            MultiPartInputStream mpis = (MultiPartInputStream)sre.getServletRequest().getAttribute(__MULTIPART_INPUT_STREAM);
-            if (mpis != null)
-            {
-                ContextHandler.Context context = (ContextHandler.Context)sre.getServletRequest().getAttribute(__MULTIPART_CONTEXT);
+		@Override
+		public void requestDestroyed(ServletRequestEvent sre)
+		{
+			//Clean up any tmp files created by MultiPartInputStream
+			MultiPartInputStream mpis = (MultiPartInputStream)sre.getServletRequest().getAttribute(__MULTIPART_INPUT_STREAM);
+			if (mpis != null)
+			{
+				ContextHandler.Context context = (ContextHandler.Context)sre.getServletRequest().getAttribute(__MULTIPART_CONTEXT);
 
-                //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files
-                if (context == sre.getServletContext())
-                {
-                    try
-                    {
-                        mpis.deleteParts();
-                    }
-                    catch (MultiException e)
-                    {
-                        sre.getServletContext().log("Errors deleting multipart tmp files", e);
-                    }
-                }
-            }
-        }
+				//Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files
+				if (context == sre.getServletContext())
+				{
+					try
+					{
+						mpis.deleteParts();
+					}
+					catch (MultiException e)
+					{
+						sre.getServletContext().log("Errors deleting multipart tmp files", e);
+					}
+				}
+			}
+		}
 
-        @Override
-        public void requestInitialized(ServletRequestEvent sre)
-        {
-            //nothing to do, multipart config set up by ServletHolder.handle()
-        }
-        
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    public static Request getRequest(HttpServletRequest request)
-    {
-        if (request instanceof Request)
-            return (Request)request;
+		@Override
+		public void requestInitialized(ServletRequestEvent sre)
+		{
+			//nothing to do, multipart config set up by ServletHolder.handle()
+		}
+		
+	}
+	
+	
+	/* ------------------------------------------------------------ */
+	public static Request getRequest(HttpServletRequest request)
+	{
+		if (request instanceof Request)
+			return (Request)request;
 
-        return AbstractHttpConnection.getCurrentConnection().getRequest();
-    }
-    protected final AsyncContinuation _async = new AsyncContinuation();
-    private boolean _asyncSupported = true;
-    private volatile Attributes _attributes;
-    private Authentication _authentication;
-    private MultiMap<String> _baseParameters;
-    private String _characterEncoding;
-    protected AbstractHttpConnection _connection;
-    private ContextHandler.Context _context;
-    private boolean _newContext;
-    private String _contextPath;
-    private CookieCutter _cookies;
-    private boolean _cookiesExtracted = false;
-    private DispatcherType _dispatcherType;
-    private boolean _dns = false;
-    private EndPoint _endp;
-    private boolean _handled = false;
-    private int _inputState = __NONE;
-    private String _method;
-    private MultiMap<String> _parameters;
-    private boolean _paramsExtracted;
-    private String _pathInfo;
-    private int _port;
-    private String _protocol = HttpVersions.HTTP_1_1;
-    private String _queryEncoding;
-    private String _queryString;
-    private BufferedReader _reader;
-    private String _readerEncoding;
-    private String _remoteAddr;
-    private String _remoteHost;
-    private Object _requestAttributeListeners;
-    private String _requestedSessionId;
-    private boolean _requestedSessionIdFromCookie = false;
-    private String _requestURI;
-    private Map<Object, HttpSession> _savedNewSessions;
-    private String _scheme = URIUtil.HTTP;
-    private UserIdentity.Scope _scope;
-    private String _serverName;
-    private String _servletPath;
-    private HttpSession _session;
-    private SessionManager _sessionManager;
-    private long _timeStamp;
-    private long _dispatchTime;
+		return AbstractHttpConnection.getCurrentConnection().getRequest();
+	}
+	protected final AsyncContinuation _async = new AsyncContinuation();
+	private boolean _asyncSupported = true;
+	private volatile Attributes _attributes;
+	private Authentication _authentication;
+	private MultiMap<String> _baseParameters;
+	private String _characterEncoding;
+	protected AbstractHttpConnection _connection;
+	private ContextHandler.Context _context;
+	private boolean _newContext;
+	private String _contextPath;
+	private CookieCutter _cookies;
+	private boolean _cookiesExtracted = false;
+	private DispatcherType _dispatcherType;
+	private boolean _dns = false;
+	private EndPoint _endp;
+	private boolean _handled = false;
+	private int _inputState = __NONE;
+	private String _method;
+	private MultiMap<String> _parameters;
+	private boolean _paramsExtracted;
+	private String _pathInfo;
+	private int _port;
+	private String _protocol = HttpVersions.HTTP_1_1;
+	private String _queryEncoding;
+	private String _queryString;
+	private BufferedReader _reader;
+	private String _readerEncoding;
+	private String _remoteAddr;
+	private String _remoteHost;
+	private Object _requestAttributeListeners;
+	private String _requestedSessionId;
+	private boolean _requestedSessionIdFromCookie = false;
+	private String _requestURI;
+	private Map<Object, HttpSession> _savedNewSessions;
+	private String _scheme = URIUtil.HTTP;
+	private UserIdentity.Scope _scope;
+	private String _serverName;
+	private String _servletPath;
+	private HttpSession _session;
+	private long _timeStamp;
+	private long _dispatchTime;
 
-    private Buffer _timeStampBuffer;
-    private HttpURI _uri;
-    
-    private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime
-    
-    /* ------------------------------------------------------------ */
-    public Request()
-    {
-    }
+	private Buffer _timeStampBuffer;
+	private HttpURI _uri;
+	
+	private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime
+	
+	/* ------------------------------------------------------------ */
+	public Request()
+	{
+	}
 
-    /* ------------------------------------------------------------ */
-    public Request(AbstractHttpConnection connection)
-    {
-        setConnection(connection);
-    }
+	/* ------------------------------------------------------------ */
+	public Request(AbstractHttpConnection connection)
+	{
+		setConnection(connection);
+	}
 
-    /* ------------------------------------------------------------ */
-    public void addEventListener(final EventListener listener)
-    {
-        if (listener instanceof ServletRequestAttributeListener)
-            _requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener);
-        if (listener instanceof ContinuationListener)
-            throw new IllegalArgumentException(listener.getClass().toString());
-        if (listener instanceof AsyncListener)
-            throw new IllegalArgumentException(listener.getClass().toString());
-    }
+	/* ------------------------------------------------------------ */
+	public void addEventListener(final EventListener listener)
+	{
+		if (listener instanceof ServletRequestAttributeListener)
+			_requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener);
+		if (listener instanceof ContinuationListener)
+			throw new IllegalArgumentException(listener.getClass().toString());
+		if (listener instanceof AsyncListener)
+			throw new IllegalArgumentException(listener.getClass().toString());
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Extract Parameters from query string and/or form _content.
-     */
-    public void extractParameters()
-    {
-        if (_baseParameters == null)
-            _baseParameters = new MultiMap(16);
+	/* ------------------------------------------------------------ */
+	/**
+	 * Extract Parameters from query string and/or form _content.
+	 */
+	public void extractParameters()
+	{
+		if (_baseParameters == null)
+			_baseParameters = new MultiMap(16);
 
-        if (_paramsExtracted)
-        {
-            if (_parameters == null)
-                _parameters = _baseParameters;
-            return;
-        }
+		if (_paramsExtracted)
+		{
+			if (_parameters == null)
+				_parameters = _baseParameters;
+			return;
+		}
 
-        _paramsExtracted = true;
+		_paramsExtracted = true;
 
-        try
-        {
-            // Handle query string
-            if (_uri != null && _uri.hasQuery())
-            {
-                if (_queryEncoding == null)
-                    _uri.decodeQueryTo(_baseParameters);
-                else
-                {
-                    try
-                    {
-                        _uri.decodeQueryTo(_baseParameters,_queryEncoding);
-                    }
-                    catch (UnsupportedEncodingException e)
-                    {
-                        if (LOG.isDebugEnabled())
-                            LOG.warn(e);
-                        else
-                            LOG.warn(e.toString());
-                    }
-                }
-            }
-
-            // handle any _content.
-            String encoding = getCharacterEncoding();
-            String content_type = getContentType();
-            if (content_type != null && content_type.length() > 0)
-            {
-                content_type = HttpFields.valueParameters(content_type,null);
+		try
+		{
+			// Handle query string
+			if (_uri != null && _uri.hasQuery())
+			{
+				if (_queryEncoding == null)
+					_uri.decodeQueryTo(_baseParameters);
+				else
+				{
+					try
+					{
+						_uri.decodeQueryTo(_baseParameters,_queryEncoding);
+					}
+					catch (UnsupportedEncodingException e)
+					{
+						if (LOG.isDebugEnabled())
+							LOG.warn(e);
+						else
+							LOG.warn(e.toString());
+					}
+				}
+			}
 
-                if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE
-                        && (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod())))
-                {
-                    int content_length = getContentLength();
-                    if (content_length != 0)
-                    {
-                        try
-                        {
-                            int maxFormContentSize = -1;
-                            int maxFormKeys = -1;
+			// handle any _content.
+			String encoding = getCharacterEncoding();
+			String content_type = getContentType();
+			if (content_type != null && content_type.length() > 0)
+			{
+				content_type = HttpFields.valueParameters(content_type,null);
 
-                            if (_context != null)
-                            {
-                                maxFormContentSize = _context.getContextHandler().getMaxFormContentSize();
-                                maxFormKeys = _context.getContextHandler().getMaxFormKeys();
-                            }
-                            
-                            if (maxFormContentSize < 0)
-                            {
-                                Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
-                                if (obj == null)
-                                    maxFormContentSize = 200000;
-                                else if (obj instanceof Number)
-                                {                      
-                                    Number size = (Number)obj;
-                                    maxFormContentSize = size.intValue();
-                                }
-                                else if (obj instanceof String)
-                                {
-                                    maxFormContentSize = Integer.valueOf((String)obj);
-                                }
-                            }
-                            
-                            if (maxFormKeys < 0)
-                            {
-                                Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
-                                if (obj == null)
-                                    maxFormKeys = 1000;
-                                else if (obj instanceof Number)
-                                {
-                                    Number keys = (Number)obj;
-                                    maxFormKeys = keys.intValue();
-                                }
-                                else if (obj instanceof String)
-                                {
-                                    maxFormKeys = Integer.valueOf((String)obj);
-                                }
-                            }
+				if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE
+						&& (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod())))
+				{
+					int content_length = getContentLength();
+					if (content_length != 0)
+					{
+						try
+						{
+							int maxFormContentSize = -1;
+							int maxFormKeys = -1;
 
-                            if (content_length > maxFormContentSize && maxFormContentSize > 0)
-                            {
-                                throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize);
-                            }
-                            InputStream in = getInputStream();
+							if (_context != null)
+							{
+								maxFormContentSize = _context.getContextHandler().getMaxFormContentSize();
+								maxFormKeys = _context.getContextHandler().getMaxFormKeys();
+							}
+							
+							if (maxFormContentSize < 0)
+							{
+								Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
+								if (obj == null)
+									maxFormContentSize = 200000;
+								else if (obj instanceof Number)
+								{                      
+									Number size = (Number)obj;
+									maxFormContentSize = size.intValue();
+								}
+								else if (obj instanceof String)
+								{
+									maxFormContentSize = Integer.valueOf((String)obj);
+								}
+							}
+							
+							if (maxFormKeys < 0)
+							{
+								Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
+								if (obj == null)
+									maxFormKeys = 1000;
+								else if (obj instanceof Number)
+								{
+									Number keys = (Number)obj;
+									maxFormKeys = keys.intValue();
+								}
+								else if (obj instanceof String)
+								{
+									maxFormKeys = Integer.valueOf((String)obj);
+								}
+							}
 
-                            // Add form params to query params
-                            UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys);
-                        }
-                        catch (IOException e)
-                        {
-                            if (LOG.isDebugEnabled())
-                                LOG.warn(e);
-                            else
-                                LOG.warn(e.toString());
-                        }
-                    }
-                }
-              
-            }
-
-            if (_parameters == null)
-                _parameters = _baseParameters;
-            else if (_parameters != _baseParameters)
-            {
-                // Merge parameters (needed if parameters extracted after a forward).
-                Iterator iter = _baseParameters.entrySet().iterator();
-                while (iter.hasNext())
-                {
-                    Map.Entry entry = (Map.Entry)iter.next();
-                    String name = (String)entry.getKey();
-                    Object values = entry.getValue();
-                    for (int i = 0; i < LazyList.size(values); i++)
-                        _parameters.add(name,LazyList.get(values,i));
-                }
-            }
+							if (content_length > maxFormContentSize && maxFormContentSize > 0)
+							{
+								throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize);
+							}
+							InputStream in = getInputStream();
 
-            if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null)
-            {
-                try
-                {
-                    getParts();
-                }
-                catch (IOException e)
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.warn(e);
-                    else
-                        LOG.warn(e.toString());
-                }
-                catch (ServletException e)
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.warn(e);
-                    else
-                        LOG.warn(e.toString());
-                }
-            }
-        }
-        finally
-        {
-            // ensure params always set (even if empty) after extraction
-            if (_parameters == null)
-                _parameters = _baseParameters;
-        }
-    }
+							// Add form params to query params
+							UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys);
+						}
+						catch (IOException e)
+						{
+							if (LOG.isDebugEnabled())
+								LOG.warn(e);
+							else
+								LOG.warn(e.toString());
+						}
+					}
+				}
+			  
+			}
+
+			if (_parameters == null)
+				_parameters = _baseParameters;
+			else if (_parameters != _baseParameters)
+			{
+				// Merge parameters (needed if parameters extracted after a forward).
+				Iterator iter = _baseParameters.entrySet().iterator();
+				while (iter.hasNext())
+				{
+					Map.Entry entry = (Map.Entry)iter.next();
+					String name = (String)entry.getKey();
+					Object values = entry.getValue();
+					for (int i = 0; i < LazyList.size(values); i++)
+						_parameters.add(name,LazyList.get(values,i));
+				}
+			}
 
-    /* ------------------------------------------------------------ */
-    public AsyncContext getAsyncContext()
-    {
-        if (_async.isInitial() && !_async.isAsyncStarted())
-            throw new IllegalStateException(_async.getStatusString());
-        return _async;
-    }
+			if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null)
+			{
+				try
+				{
+					getParts();
+				}
+				catch (IOException e)
+				{
+					if (LOG.isDebugEnabled())
+						LOG.warn(e);
+					else
+						LOG.warn(e.toString());
+				}
+				catch (ServletException e)
+				{
+					if (LOG.isDebugEnabled())
+						LOG.warn(e);
+					else
+						LOG.warn(e.toString());
+				}
+			}
+		}
+		finally
+		{
+			// ensure params always set (even if empty) after extraction
+			if (_parameters == null)
+				_parameters = _baseParameters;
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public AsyncContinuation getAsyncContinuation()
-    {
-        return _async;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
-     */
-    public Object getAttribute(String name)
-    {
-        if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name))
-            return new Long(getConnection().getEndPoint().getMaxIdleTime());
+	/* ------------------------------------------------------------ */
+	public AsyncContext getAsyncContext()
+	{
+		if (_async.isInitial() && !_async.isAsyncStarted())
+			throw new IllegalStateException(_async.getStatusString());
+		return _async;
+	}
 
-        Object attr = (_attributes == null)?null:_attributes.getAttribute(name);
-        if (attr == null && Continuation.ATTRIBUTE.equals(name))
-            return _async;
-        return attr;
-    }
+	/* ------------------------------------------------------------ */
+	public AsyncContinuation getAsyncContinuation()
+	{
+		return _async;
+	}
+	
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
+	 */
+	public Object getAttribute(String name)
+	{
+		if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name))
+			return new Long(getConnection().getEndPoint().getMaxIdleTime());
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getAttributeNames()
-     */
-    public Enumeration getAttributeNames()
-    {
-        if (_attributes == null)
-            return Collections.enumeration(Collections.EMPTY_LIST);
+		Object attr = (_attributes == null)?null:_attributes.getAttribute(name);
+		if (attr == null && Continuation.ATTRIBUTE.equals(name))
+			return _async;
+		return attr;
+	}
 
-        return AttributesMap.getAttributeNamesCopy(_attributes);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getAttributeNames()
+	 */
+	public Enumeration getAttributeNames()
+	{
+		if (_attributes == null)
+			return Collections.enumeration(Collections.EMPTY_LIST);
 
-    /* ------------------------------------------------------------ */
-    /*
-     */
-    public Attributes getAttributes()
-    {
-        if (_attributes == null)
-            _attributes = new AttributesMap();
-        return _attributes;
-    }
+		return AttributesMap.getAttributeNamesCopy(_attributes);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Get the authentication.
-     *
-     * @return the authentication
-     */
-    public Authentication getAuthentication()
-    {
-        return _authentication;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 */
+	public Attributes getAttributes()
+	{
+		if (_attributes == null)
+			_attributes = new AttributesMap();
+		return _attributes;
+	}
+
+	/* ------------------------------------------------------------ */
+	/**
+	 * Get the authentication.
+	 *
+	 * @return the authentication
+	 */
+	public Authentication getAuthentication()
+	{
+		return _authentication;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getAuthType()
-     */
-    public String getAuthType()
-    {
-        if (_authentication instanceof Authentication.Deferred)
-            setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
-        
-        if (_authentication instanceof Authentication.User)
-            return ((Authentication.User)_authentication).getAuthMethod();
-        return null;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getAuthType()
+	 */
+	public String getAuthType()
+	{
+		if (_authentication instanceof Authentication.Deferred)
+			setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
+		
+		if (_authentication instanceof Authentication.User)
+			return ((Authentication.User)_authentication).getAuthMethod();
+		return null;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getCharacterEncoding()
-     */
-    public String getCharacterEncoding()
-    {
-        return _characterEncoding;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the connection.
-     */
-    public AbstractHttpConnection getConnection()
-    {
-        return _connection;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getCharacterEncoding()
+	 */
+	public String getCharacterEncoding()
+	{
+		return _characterEncoding;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getContentLength()
-     */
-    public int getContentLength()
-    {
-        return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER);
-    }
-
-    public long getContentRead()
-    {
-        if (_connection == null || _connection.getParser() == null)
-            return -1;
-
-        return ((HttpParser)_connection.getParser()).getContentRead();
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the connection.
+	 */
+	public AbstractHttpConnection getConnection()
+	{
+		return _connection;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getContentType()
-     */
-    public String getContentType()
-    {
-        return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_BUFFER);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getContentLength()
+	 */
+	public int getContentLength()
+	{
+		return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return The current {@link Context context} used for this request, or <code>null</code> if {@link #setContext} has not yet been called.
-     */
-    public Context getContext()
-    {
-        return _context;
-    }
+	public long getContentRead()
+	{
+		if (_connection == null || _connection.getParser() == null)
+			return -1;
+
+		return ((HttpParser)_connection.getParser()).getContentRead();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getContextPath()
-     */
-    public String getContextPath()
-    {
-        return _contextPath;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getContentType()
+	 */
+	public String getContentType()
+	{
+		return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_BUFFER);
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getCookies()
-     */
-    public Cookie[] getCookies()
-    {
-        if (_cookiesExtracted)
-            return _cookies == null?null:_cookies.getCookies();
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return The current {@link Context context} used for this request, or <code>null</code> if {@link #setContext} has not yet been called.
+	 */
+	public Context getContext()
+	{
+		return _context;
+	}
 
-        _cookiesExtracted = true;
-
-        Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER);
-
-        // Handle no cookies
-        if (enm != null)
-        {
-            if (_cookies == null)
-                _cookies = new CookieCutter();
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getContextPath()
+	 */
+	public String getContextPath()
+	{
+		return _contextPath;
+	}
 
-            while (enm.hasMoreElements())
-            {
-                String c = (String)enm.nextElement();
-                _cookies.addCookieField(c);
-            }
-        }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getCookies()
+	 */
+	public Cookie[] getCookies()
+	{
+		if (_cookiesExtracted)
+			return _cookies == null?null:_cookies.getCookies();
 
-        return _cookies == null?null:_cookies.getCookies();
-    }
+		_cookiesExtracted = true;
+
+		Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER);
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String)
-     */
-    public long getDateHeader(String name)
-    {
-        return _connection.getRequestFields().getDateField(name);
-    }
+		// Handle no cookies
+		if (enm != null)
+		{
+			if (_cookies == null)
+				_cookies = new CookieCutter();
 
-    /* ------------------------------------------------------------ */
-    public DispatcherType getDispatcherType()
-    {
-        return _dispatcherType;
-    }
+			while (enm.hasMoreElements())
+			{
+				String c = (String)enm.nextElement();
+				_cookies.addCookieField(c);
+			}
+		}
+
+		return _cookies == null?null:_cookies.getCookies();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
-     */
-    public String getHeader(String name)
-    {
-        return _connection.getRequestFields().getStringField(name);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String)
+	 */
+	public long getDateHeader(String name)
+	{
+		return _connection.getRequestFields().getDateField(name);
+	}
+
+	/* ------------------------------------------------------------ */
+	public DispatcherType getDispatcherType()
+	{
+		return _dispatcherType;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
-     */
-    public Enumeration getHeaderNames()
-    {
-        return _connection.getRequestFields().getFieldNames();
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
+	 */
+	public String getHeader(String name)
+	{
+		return _connection.getRequestFields().getStringField(name);
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
-     */
-    public Enumeration getHeaders(String name)
-    {
-        Enumeration e = _connection.getRequestFields().getValues(name);
-        if (e == null)
-            return Collections.enumeration(Collections.EMPTY_LIST);
-        return e;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getHeaderNames()
+	 */
+	public Enumeration getHeaderNames()
+	{
+		return _connection.getRequestFields().getFieldNames();
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the inputState.
-     */
-    public int getInputState()
-    {
-        return _inputState;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String)
+	 */
+	public Enumeration getHeaders(String name)
+	{
+		Enumeration e = _connection.getRequestFields().getValues(name);
+		if (e == null)
+			return Collections.enumeration(Collections.EMPTY_LIST);
+		return e;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getInputStream()
-     */
-    public ServletInputStream getInputStream() throws IOException
-    {
-        if (_inputState != __NONE && _inputState != _STREAM)
-            throw new IllegalStateException("READER");
-        _inputState = _STREAM;
-        return _connection.getInputStream();
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the inputState.
+	 */
+	public int getInputState()
+	{
+		return _inputState;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String)
-     */
-    public int getIntHeader(String name)
-    {
-        return (int)_connection.getRequestFields().getLongField(name);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getInputStream()
+	 */
+	public ServletInputStream getInputStream() throws IOException
+	{
+		if (_inputState != __NONE && _inputState != _STREAM)
+			throw new IllegalStateException("READER");
+		_inputState = _STREAM;
+		return _connection.getInputStream();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getLocalAddr()
-     */
-    public String getLocalAddr()
-    {
-        return _endp == null?null:_endp.getLocalAddr();
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getLocale()
-     */
-    public Locale getLocale()
-    {
-        Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators);
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String)
+	 */
+	public int getIntHeader(String name)
+	{
+		return (int)_connection.getRequestFields().getLongField(name);
+	}
 
-        // handle no locale
-        if (enm == null || !enm.hasMoreElements())
-            return Locale.getDefault();
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getLocalAddr()
+	 */
+	public String getLocalAddr()
+	{
+		return _endp == null?null:_endp.getLocalAddr();
+	}
 
-        // sort the list in quality order
-        List acceptLanguage = HttpFields.qualityList(enm);
-        if (acceptLanguage.size() == 0)
-            return Locale.getDefault();
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getLocale()
+	 */
+	public Locale getLocale()
+	{
+		Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators);
 
-        int size = acceptLanguage.size();
+		// handle no locale
+		if (enm == null || !enm.hasMoreElements())
+			return Locale.getDefault();
 
-        if (size > 0)
-        {
-            String language = (String)acceptLanguage.get(0);
-            language = HttpFields.valueParameters(language,null);
-            String country = "";
-            int dash = language.indexOf('-');
-            if (dash > -1)
-            {
-                country = language.substring(dash + 1).trim();
-                language = language.substring(0,dash).trim();
-            }
-            return new Locale(language,country);
-        }
+		// sort the list in quality order
+		List acceptLanguage = HttpFields.qualityList(enm);
+		if (acceptLanguage.size() == 0)
+			return Locale.getDefault();
+
+		int size = acceptLanguage.size();
 
-        return Locale.getDefault();
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getLocales()
-     */
-    public Enumeration getLocales()
-    {
-
-        Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators);
-
-        // handle no locale
-        if (enm == null || !enm.hasMoreElements())
-            return Collections.enumeration(__defaultLocale);
+		if (size > 0)
+		{
+			String language = (String)acceptLanguage.get(0);
+			language = HttpFields.valueParameters(language,null);
+			String country = "";
+			int dash = language.indexOf('-');
+			if (dash > -1)
+			{
+				country = language.substring(dash + 1).trim();
+				language = language.substring(0,dash).trim();
+			}
+			return new Locale(language,country);
+		}
 
-        // sort the list in quality order
-        List acceptLanguage = HttpFields.qualityList(enm);
+		return Locale.getDefault();
+	}
+
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getLocales()
+	 */
+	public Enumeration getLocales()
+	{
 
-        if (acceptLanguage.size() == 0)
-            return Collections.enumeration(__defaultLocale);
+		Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators);
+
+		// handle no locale
+		if (enm == null || !enm.hasMoreElements())
+			return Collections.enumeration(__defaultLocale);
 
-        Object langs = null;
-        int size = acceptLanguage.size();
+		// sort the list in quality order
+		List acceptLanguage = HttpFields.qualityList(enm);
+
+		if (acceptLanguage.size() == 0)
+			return Collections.enumeration(__defaultLocale);
 
-        // convert to locals
-        for (int i = 0; i < size; i++)
-        {
-            String language = (String)acceptLanguage.get(i);
-            language = HttpFields.valueParameters(language,null);
-            String country = "";
-            int dash = language.indexOf('-');
-            if (dash > -1)
-            {
-                country = language.substring(dash + 1).trim();
-                language = language.substring(0,dash).trim();
-            }
-            langs = LazyList.ensureSize(langs,size);
-            langs = LazyList.add(langs,new Locale(language,country));
-        }
+		Object langs = null;
+		int size = acceptLanguage.size();
 
-        if (LazyList.size(langs) == 0)
-            return Collections.enumeration(__defaultLocale);
-
-        return Collections.enumeration(LazyList.getList(langs));
-    }
+		// convert to locals
+		for (int i = 0; i < size; i++)
+		{
+			String language = (String)acceptLanguage.get(i);
+			language = HttpFields.valueParameters(language,null);
+			String country = "";
+			int dash = language.indexOf('-');
+			if (dash > -1)
+			{
+				country = language.substring(dash + 1).trim();
+				language = language.substring(0,dash).trim();
+			}
+			langs = LazyList.ensureSize(langs,size);
+			langs = LazyList.add(langs,new Locale(language,country));
+		}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getLocalName()
-     */
-    public String getLocalName()
-    {
-        if (_endp == null)
-            return null;
-        if (_dns)
-            return _endp.getLocalHost();
+		if (LazyList.size(langs) == 0)
+			return Collections.enumeration(__defaultLocale);
 
-        String local = _endp.getLocalAddr();
-        if (local != null && local.indexOf(':') >= 0)
-            local = "[" + local + "]";
-        return local;
-    }
+		return Collections.enumeration(LazyList.getList(langs));
+	}
+
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getLocalName()
+	 */
+	public String getLocalName()
+	{
+		if (_endp == null)
+			return null;
+		if (_dns)
+			return _endp.getLocalHost();
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getLocalPort()
-     */
-    public int getLocalPort()
-    {
-        return _endp == null?0:_endp.getLocalPort();
-    }
+		String local = _endp.getLocalAddr();
+		if (local != null && local.indexOf(':') >= 0)
+			local = "[" + local + "]";
+		return local;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getMethod()
-     */
-    public String getMethod()
-    {
-        return _method;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getLocalPort()
+	 */
+	public int getLocalPort()
+	{
+		return _endp == null?0:_endp.getLocalPort();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
-     */
-    public String getParameter(String name)
-    {
-        if (!_paramsExtracted)
-            extractParameters();
-        return (String)_parameters.getValue(name,0);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getMethod()
+	 */
+	public String getMethod()
+	{
+		return _method;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getParameterMap()
-     */
-    public Map getParameterMap()
-    {
-        if (!_paramsExtracted)
-            extractParameters();
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
+	 */
+	public String getParameter(String name)
+	{
+		if (!_paramsExtracted)
+			extractParameters();
+		return (String)_parameters.getValue(name,0);
+	}
 
-        return Collections.unmodifiableMap(_parameters.toStringArrayMap());
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getParameterMap()
+	 */
+	public Map getParameterMap()
+	{
+		if (!_paramsExtracted)
+			extractParameters();
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getParameterNames()
-     */
-    public Enumeration getParameterNames()
-    {
-        if (!_paramsExtracted)
-            extractParameters();
-        return Collections.enumeration(_parameters.keySet());
-    }
+		return Collections.unmodifiableMap(_parameters.toStringArrayMap());
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the parameters.
-     */
-    public MultiMap<String> getParameters()
-    {
-        return _parameters;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getParameterNames()
+	 */
+	public Enumeration getParameterNames()
+	{
+		if (!_paramsExtracted)
+			extractParameters();
+		return Collections.enumeration(_parameters.keySet());
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
-     */
-    public String[] getParameterValues(String name)
-    {
-        if (!_paramsExtracted)
-            extractParameters();
-        List<Object> vals = _parameters.getValues(name);
-        if (vals == null)
-            return null;
-        return vals.toArray(new String[vals.size()]);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the parameters.
+	 */
+	public MultiMap<String> getParameters()
+	{
+		return _parameters;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getPathInfo()
-     */
-    public String getPathInfo()
-    {
-        return _pathInfo;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
+	 */
+	public String[] getParameterValues(String name)
+	{
+		if (!_paramsExtracted)
+			extractParameters();
+		List<Object> vals = _parameters.getValues(name);
+		if (vals == null)
+			return null;
+		return vals.toArray(new String[vals.size()]);
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
-     */
-    public String getPathTranslated()
-    {
-        if (_pathInfo == null || _context == null)
-            return null;
-        return _context.getRealPath(_pathInfo);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getPathInfo()
+	 */
+	public String getPathInfo()
+	{
+		return _pathInfo;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getProtocol()
-     */
-    public String getProtocol()
-    {
-        return _protocol;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
+	 */
+	public String getPathTranslated()
+	{
+		if (_pathInfo == null || _context == null)
+			return null;
+		return _context.getRealPath(_pathInfo);
+	}
 
-    /* ------------------------------------------------------------ */
-    public String getQueryEncoding()
-    {
-        return _queryEncoding;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getProtocol()
+	 */
+	public String getProtocol()
+	{
+		return _protocol;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getQueryString()
-     */
-    public String getQueryString()
-    {
-        if (_queryString == null && _uri != null)
-        {
-            if (_queryEncoding == null)
-                _queryString = _uri.getQuery();
-            else
-                _queryString = _uri.getQuery(_queryEncoding);
-        }
-        return _queryString;
-    }
+	/* ------------------------------------------------------------ */
+	public String getQueryEncoding()
+	{
+		return _queryEncoding;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getReader()
-     */
-    public BufferedReader getReader() throws IOException
-    {
-        if (_inputState != __NONE && _inputState != __READER)
-            throw new IllegalStateException("STREAMED");
-
-        if (_inputState == __READER)
-            return _reader;
-
-        String encoding = getCharacterEncoding();
-        if (encoding == null)
-            encoding = StringUtil.__ISO_8859_1;
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getQueryString()
+	 */
+	public String getQueryString()
+	{
+		if (_queryString == null && _uri != null)
+		{
+			if (_queryEncoding == null)
+				_queryString = _uri.getQuery();
+			else
+				_queryString = _uri.getQuery(_queryEncoding);
+		}
+		return _queryString;
+	}
 
-        if (_reader == null || !encoding.equalsIgnoreCase(_readerEncoding))
-        {
-            final ServletInputStream in = getInputStream();
-            _readerEncoding = encoding;
-            _reader = new BufferedReader(new InputStreamReader(in,encoding))
-            {
-                @Override
-                public void close() throws IOException
-                {
-                    in.close();
-                }
-            };
-        }
-        _inputState = __READER;
-        return _reader;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getReader()
+	 */
+	public BufferedReader getReader() throws IOException
+	{
+		if (_inputState != __NONE && _inputState != __READER)
+			throw new IllegalStateException("STREAMED");
+
+		if (_inputState == __READER)
+			return _reader;
+
+		String encoding = getCharacterEncoding();
+		if (encoding == null)
+			encoding = StringUtil.__ISO_8859_1;
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getRealPath(java.lang.String)
-     */
-    public String getRealPath(String path)
-    {
-        if (_context == null)
-            return null;
-        return _context.getRealPath(path);
-    }
+		if (_reader == null || !encoding.equalsIgnoreCase(_readerEncoding))
+		{
+			final ServletInputStream in = getInputStream();
+			_readerEncoding = encoding;
+			_reader = new BufferedReader(new InputStreamReader(in,encoding))
+			{
+				@Override
+				public void close() throws IOException
+				{
+					in.close();
+				}
+			};
+		}
+		_inputState = __READER;
+		return _reader;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getRemoteAddr()
-     */
-    public String getRemoteAddr()
-    {
-        if (_remoteAddr != null)
-            return _remoteAddr;
-        return _endp == null?null:_endp.getRemoteAddr();
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getRealPath(java.lang.String)
+	 */
+	public String getRealPath(String path)
+	{
+		if (_context == null)
+			return null;
+		return _context.getRealPath(path);
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getRemoteHost()
-     */
-    public String getRemoteHost()
-    {
-        if (_dns)
-        {
-            if (_remoteHost != null)
-            {
-                return _remoteHost;
-            }
-            return _endp == null?null:_endp.getRemoteHost();
-        }
-        return getRemoteAddr();
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getRemoteAddr()
+	 */
+	public String getRemoteAddr()
+	{
+		if (_remoteAddr != null)
+			return _remoteAddr;
+		return _endp == null?null:_endp.getRemoteAddr();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getRemotePort()
-     */
-    public int getRemotePort()
-    {
-        return _endp == null?0:_endp.getRemotePort();
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getRemoteHost()
+	 */
+	public String getRemoteHost()
+	{
+		if (_dns)
+		{
+			if (_remoteHost != null)
+			{
+				return _remoteHost;
+			}
+			return _endp == null?null:_endp.getRemoteHost();
+		}
+		return getRemoteAddr();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
-     */
-    public String getRemoteUser()
-    {
-        Principal p = getUserPrincipal();
-        if (p == null)
-            return null;
-        return p.getName();
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getRemotePort()
+	 */
+	public int getRemotePort()
+	{
+		return _endp == null?0:_endp.getRemotePort();
+	}
+
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
+	 */
+	public String getRemoteUser()
+	{
+		Principal p = getUserPrincipal();
+		if (p == null)
+			return null;
+		return p.getName();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String)
-     */
-    public RequestDispatcher getRequestDispatcher(String path)
-    {
-        if (path == null || _context == null)
-            return null;
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String)
+	 */
+	public RequestDispatcher getRequestDispatcher(String path)
+	{
+		if (path == null || _context == null)
+			return null;
 
-        // handle relative path
-        if (!path.startsWith("/"))
-        {
-            String relTo = URIUtil.addPaths(_servletPath,_pathInfo);
-            int slash = relTo.lastIndexOf("/");
-            if (slash > 1)
-                relTo = relTo.substring(0,slash + 1);
-            else
-                relTo = "/";
-            path = URIUtil.addPaths(relTo,path);
-        }
-
-        return _context.getRequestDispatcher(path);
-    }
+		// handle relative path
+		if (!path.startsWith("/"))
+		{
+			String relTo = URIUtil.addPaths(_servletPath,_pathInfo);
+			int slash = relTo.lastIndexOf("/");
+			if (slash > 1)
+				relTo = relTo.substring(0,slash + 1);
+			else
+				relTo = "/";
+			path = URIUtil.addPaths(relTo,path);
+		}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
-     */
-    public String getRequestedSessionId()
-    {
-        return _requestedSessionId;
-    }
+		return _context.getRequestDispatcher(path);
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getRequestURI()
-     */
-    public String getRequestURI()
-    {
-        if (_requestURI == null && _uri != null)
-            _requestURI = _uri.getPathAndParam();
-        return _requestURI;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
+	 */
+	public String getRequestedSessionId()
+	{
+		return _requestedSessionId;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getRequestURL()
-     */
-    public StringBuffer getRequestURL()
-    {
-        final StringBuffer url = new StringBuffer(48);
-        synchronized (url)
-        {
-            String scheme = getScheme();
-            int port = getServerPort();
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getRequestURI()
+	 */
+	public String getRequestURI()
+	{
+		if (_requestURI == null && _uri != null)
+			_requestURI = _uri.getPathAndParam();
+		return _requestURI;
+	}
 
-            url.append(scheme);
-            url.append("://");
-            url.append(getServerName());
-            if (_port > 0 && ((scheme.equalsIgnoreCase(URIUtil.HTTP) && port != 80) || (scheme.equalsIgnoreCase(URIUtil.HTTPS) && port != 443)))
-            {
-                url.append(':');
-                url.append(_port);
-            }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getRequestURL()
+	 */
+	public StringBuffer getRequestURL()
+	{
+		final StringBuffer url = new StringBuffer(48);
+		synchronized (url)
+		{
+			String scheme = getScheme();
+			int port = getServerPort();
 
-            url.append(getRequestURI());
-            return url;
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    public Response getResponse()
-    {
-        return _connection._response;
-    }
+			url.append(scheme);
+			url.append("://");
+			url.append(getServerName());
+			if (_port > 0 && ((scheme.equalsIgnoreCase(URIUtil.HTTP) && port != 80) || (scheme.equalsIgnoreCase(URIUtil.HTTPS) && port != 443)))
+			{
+				url.append(':');
+				url.append(_port);
+			}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and, but it does not include a
-     * path.
-     * <p>
-     * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the URL easily, for example, to append path and query parameters.
-     *
-     * This method is useful for creating redirect messages and for reporting errors.
-     *
-     * @return "scheme://host:port"
-     */
-    public StringBuilder getRootURL()
-    {
-        StringBuilder url = new StringBuilder(48);
-        String scheme = getScheme();
-        int port = getServerPort();
+			url.append(getRequestURI());
+			return url;
+		}
+	}
+
+	/* ------------------------------------------------------------ */
+	public Response getResponse()
+	{
+		return _connection._response;
+	}
 
-        url.append(scheme);
-        url.append("://");
-        url.append(getServerName());
+	/* ------------------------------------------------------------ */
+	/**
+	 * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and, but it does not include a
+	 * path.
+	 * <p>
+	 * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the URL easily, for example, to append path and query parameters.
+	 *
+	 * This method is useful for creating redirect messages and for reporting errors.
+	 *
+	 * @return "scheme://host:port"
+	 */
+	public StringBuilder getRootURL()
+	{
+		StringBuilder url = new StringBuilder(48);
+		String scheme = getScheme();
+		int port = getServerPort();
 
-        if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443)))
-        {
-            url.append(':');
-            url.append(port);
-        }
-        return url;
-    }
+		url.append(scheme);
+		url.append("://");
+		url.append(getServerName());
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getScheme()
-     */
-    public String getScheme()
-    {
-        return _scheme;
-    }
+		if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443)))
+		{
+			url.append(':');
+			url.append(port);
+		}
+		return url;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getServerName()
-     */
-    public String getServerName()
-    {
-        // Return already determined host
-        if (_serverName != null)
-            return _serverName;
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getScheme()
+	 */
+	public String getScheme()
+	{
+		return _scheme;
+	}
 
-        if (_uri == null)
-            throw new IllegalStateException("No uri");
-
-        // Return host from absolute URI
-        _serverName = _uri.getHost();
-        _port = _uri.getPort();
-        if (_serverName != null)
-            return _serverName;
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getServerName()
+	 */
+	public String getServerName()
+	{
+		// Return already determined host
+		if (_serverName != null)
+			return _serverName;
 
-        // Return host from header field
-        Buffer hostPort = _connection.getRequestFields().get(HttpHeaders.HOST_BUFFER);
-        if (hostPort != null)
-        {
-            loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();)
-            {
-                char ch = (char)(0xff & hostPort.peek(i));
-                switch (ch)
-                {
-                    case ']':
-                        break loop;
+		if (_uri == null)
+			throw new IllegalStateException("No uri");
+
+		// Return host from absolute URI
+		_serverName = _uri.getHost();
+		_port = _uri.getPort();
+		if (_serverName != null)
+			return _serverName;
 
-                    case ':':
-                        _serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex()));
-                        try
-                        {
-                            _port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1));
-                        }
-                        catch (NumberFormatException e)
-                        {
-                            try
-                            {
-                                if (_connection != null)
-                                    _connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true);
-                            }
-                            catch (IOException e1)
-                            {
-                                throw new RuntimeException(e1);
-                            }
-                        }
-                        return _serverName;
-                }
-            }
-            if (_serverName == null || _port < 0)
-            {
-                _serverName = BufferUtil.to8859_1_String(hostPort);
-                _port = 0;
-            }
+		// Return host from header field
+		Buffer hostPort = _connection.getRequestFields().get(HttpHeaders.HOST_BUFFER);
+		if (hostPort != null)
+		{
+			loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();)
+			{
+				char ch = (char)(0xff & hostPort.peek(i));
+				switch (ch)
+				{
+					case ']':
+						break loop;
 
-            return _serverName;
-        }
-
-        // Return host from connection
-        if (_connection != null)
-        {
-            _serverName = getLocalName();
-            _port = getLocalPort();
-            if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName))
-                return _serverName;
-        }
+					case ':':
+						_serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex()));
+						try
+						{
+							_port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1));
+						}
+						catch (NumberFormatException e)
+						{
+							try
+							{
+								if (_connection != null)
+									_connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true);
+							}
+							catch (IOException e1)
+							{
+								throw new RuntimeException(e1);
+							}
+						}
+						return _serverName;
+				}
+			}
+			if (_serverName == null || _port < 0)
+			{
+				_serverName = BufferUtil.to8859_1_String(hostPort);
+				_port = 0;
+			}
 
-        // Return the local host
-        try
-        {
-            _serverName = InetAddress.getLocalHost().getHostAddress();
-        }
-        catch (java.net.UnknownHostException e)
-        {
-            LOG.ignore(e);
-        }
-        return _serverName;
-    }
+			return _serverName;
+		}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getServerPort()
-     */
-    public int getServerPort()
-    {
-        if (_port <= 0)
-        {
-            if (_serverName == null)
-                getServerName();
+		// Return host from connection
+		if (_connection != null)
+		{
+			_serverName = getLocalName();
+			_port = getLocalPort();
+			if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName))
+				return _serverName;
+		}
 
-            if (_port <= 0)
-            {
-                if (_serverName != null && _uri != null)
-                    _port = _uri.getPort();
-                else
-                    _port = _endp == null?0:_endp.getLocalPort();
-            }
-        }
+		// Return the local host
+		try
+		{
+			_serverName = InetAddress.getLocalHost().getHostAddress();
+		}
+		catch (java.net.UnknownHostException e)
+		{
+			LOG.ignore(e);
+		}
+		return _serverName;
+	}
 
-        if (_port <= 0)
-        {
-            if (getScheme().equalsIgnoreCase(URIUtil.HTTPS))
-                return 443;
-            return 80;
-        }
-        return _port;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getServerPort()
+	 */
+	public int getServerPort()
+	{
+		if (_port <= 0)
+		{
+			if (_serverName == null)
+				getServerName();
 
-    /* ------------------------------------------------------------ */
-    public ServletContext getServletContext()
-    {
-        return _context;
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     */
-    public String getServletName()
-    {
-        if (_scope != null)
-            return _scope.getName();
-        return null;
-    }
+			if (_port <= 0)
+			{
+				if (_serverName != null && _uri != null)
+					_port = _uri.getPort();
+				else
+					_port = _endp == null?0:_endp.getLocalPort();
+			}
+		}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getServletPath()
-     */
-    public String getServletPath()
-    {
-        if (_servletPath == null)
-            _servletPath = "";
-        return _servletPath;
-    }
+		if (_port <= 0)
+		{
+			if (getScheme().equalsIgnoreCase(URIUtil.HTTPS))
+				return 443;
+			return 80;
+		}
+		return _port;
+	}
 
-    /* ------------------------------------------------------------ */
-    public ServletResponse getServletResponse()
-    {
-        return _connection.getResponse();
-    }
+	/* ------------------------------------------------------------ */
+	public ServletContext getServletContext()
+	{
+		return _context;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getSession()
-     */
-    public HttpSession getSession()
-    {
-        return getSession(true);
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 */
+	public String getServletName()
+	{
+		if (_scope != null)
+			return _scope.getName();
+		return null;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
-     */
-    public HttpSession getSession(boolean create)
-    {
-        if (_session != null)
-        {
-            if (_sessionManager != null && !_sessionManager.isValid(_session))
-                _session = null;
-            else
-                return _session;
-        }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getServletPath()
+	 */
+	public String getServletPath()
+	{
+		if (_servletPath == null)
+			_servletPath = "";
+		return _servletPath;
+	}
 
-        if (!create)
-            return null;
-
-        if (_sessionManager == null)
-            throw new IllegalStateException("No SessionManager");
+	/* ------------------------------------------------------------ */
+	public ServletResponse getServletResponse()
+	{
+		return _connection.getResponse();
+	}
 
-        _session = _sessionManager.newHttpSession(this);
-        HttpCookie cookie = _sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
-        if (cookie != null)
-            _connection.getResponse().addCookie(cookie);
-
-        return _session;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getSession()
+	 */
+	public HttpSession getSession()
+	{
+		return getSession(true);
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the sessionManager.
-     */
-    public SessionManager getSessionManager()
-    {
-        return _sessionManager;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
+	 */
+	public HttpSession getSession(boolean create)
+	{
+		throw new UnsupportedOperationException();
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Get Request TimeStamp
-     *
-     * @return The time that the request was received.
-     */
-    public long getTimeStamp()
-    {
-        return _timeStamp;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Get Request TimeStamp
+	 *
+	 * @return The time that the request was received.
+	 */
+	public long getTimeStamp()
+	{
+		return _timeStamp;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Get Request TimeStamp
-     *
-     * @return The time that the request was received.
-     */
-    public Buffer getTimeStampBuffer()
-    {
-        if (_timeStampBuffer == null && _timeStamp > 0)
-            _timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp);
-        return _timeStampBuffer;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Get Request TimeStamp
+	 *
+	 * @return The time that the request was received.
+	 */
+	public Buffer getTimeStampBuffer()
+	{
+		if (_timeStampBuffer == null && _timeStamp > 0)
+			_timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp);
+		return _timeStampBuffer;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the uri.
-     */
-    public HttpURI getUri()
-    {
-        return _uri;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return Returns the uri.
+	 */
+	public HttpURI getUri()
+	{
+		return _uri;
+	}
 
-    /* ------------------------------------------------------------ */
-    public UserIdentity getUserIdentity()
-    {
-        if (_authentication instanceof Authentication.Deferred)
-            setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
+	/* ------------------------------------------------------------ */
+	public UserIdentity getUserIdentity()
+	{
+		if (_authentication instanceof Authentication.Deferred)
+			setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
 
-        if (_authentication instanceof Authentication.User)
-            return ((Authentication.User)_authentication).getUserIdentity();
-        return null;
-    }
+		if (_authentication instanceof Authentication.User)
+			return ((Authentication.User)_authentication).getUserIdentity();
+		return null;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return The resolved user Identity, which may be null if the {@link Authentication} is not {@link Authentication.User} (eg.
-     *         {@link Authentication.Deferred}).
-     */
-    public UserIdentity getResolvedUserIdentity()
-    {
-        if (_authentication instanceof Authentication.User)
-            return ((Authentication.User)_authentication).getUserIdentity();
-        return null;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return The resolved user Identity, which may be null if the {@link Authentication} is not {@link Authentication.User} (eg.
+	 *         {@link Authentication.Deferred}).
+	 */
+	public UserIdentity getResolvedUserIdentity()
+	{
+		if (_authentication instanceof Authentication.User)
+			return ((Authentication.User)_authentication).getUserIdentity();
+		return null;
+	}
 
-    /* ------------------------------------------------------------ */
-    public UserIdentity.Scope getUserIdentityScope()
-    {
-        return _scope;
-    }
+	/* ------------------------------------------------------------ */
+	public UserIdentity.Scope getUserIdentityScope()
+	{
+		return _scope;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
-     */
-    public Principal getUserPrincipal()
-    {
-        if (_authentication instanceof Authentication.Deferred)
-            setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
+	 */
+	public Principal getUserPrincipal()
+	{
+		if (_authentication instanceof Authentication.Deferred)
+			setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
 
-        if (_authentication instanceof Authentication.User)
-        {
-            UserIdentity user = ((Authentication.User)_authentication).getUserIdentity();
-            return user.getUserPrincipal();
-        }
-        
-        return null;
-    }
+		if (_authentication instanceof Authentication.User)
+		{
+			UserIdentity user = ((Authentication.User)_authentication).getUserIdentity();
+			return user.getUserPrincipal();
+		}
+		
+		return null;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Get timestamp of the request dispatch
-     *
-     * @return timestamp
-     */
-    public long getDispatchTime()
-    {
-        return _dispatchTime;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Get timestamp of the request dispatch
+	 *
+	 * @return timestamp
+	 */
+	public long getDispatchTime()
+	{
+		return _dispatchTime;
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean isHandled()
-    {
-        return _handled;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isHandled()
+	{
+		return _handled;
+	}
 
-    public boolean isAsyncStarted()
-    {
-       return _async.isAsyncStarted();
-    }
+	public boolean isAsyncStarted()
+	{
+	   return _async.isAsyncStarted();
+	}
 
 
-    /* ------------------------------------------------------------ */
-    public boolean isAsyncSupported()
-    {
-        return _asyncSupported;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean isAsyncSupported()
+	{
+		return _asyncSupported;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
-     */
-    public boolean isRequestedSessionIdFromCookie()
-    {
-        return _requestedSessionId != null && _requestedSessionIdFromCookie;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
+	 */
+	public boolean isRequestedSessionIdFromCookie()
+	{
+		return _requestedSessionId != null && _requestedSessionIdFromCookie;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
-     */
-    public boolean isRequestedSessionIdFromUrl()
-    {
-        return _requestedSessionId != null && !_requestedSessionIdFromCookie;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
+	 */
+	public boolean isRequestedSessionIdFromUrl()
+	{
+		return _requestedSessionId != null && !_requestedSessionIdFromCookie;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
-     */
-    public boolean isRequestedSessionIdFromURL()
-    {
-        return _requestedSessionId != null && !_requestedSessionIdFromCookie;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
+	 */
+	public boolean isRequestedSessionIdFromURL()
+	{
+		return _requestedSessionId != null && !_requestedSessionIdFromCookie;
+	}
+
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
+	 */
+	public boolean isRequestedSessionIdValid()
+	{
+		throw new UnsupportedOperationException();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
-     */
-    public boolean isRequestedSessionIdValid()
-    {
-        if (_requestedSessionId == null)
-            return false;
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#isSecure()
+	 */
+	public boolean isSecure()
+	{
+		return _connection.isConfidential(this);
+	}
 
-        HttpSession session = getSession(false);
-        return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session)));
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
+	 */
+	public boolean isUserInRole(String role)
+	{
+		if (_authentication instanceof Authentication.Deferred)
+			setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#isSecure()
-     */
-    public boolean isSecure()
-    {
-        return _connection.isConfidential(this);
-    }
+		if (_authentication instanceof Authentication.User)
+			return ((Authentication.User)_authentication).isUserInRole(_scope,role);
+		return false;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
-     */
-    public boolean isUserInRole(String role)
-    {
-        if (_authentication instanceof Authentication.Deferred)
-            setAuthentication(((Authentication.Deferred)_authentication).authenticate(this));
+	/* ------------------------------------------------------------ */
+	public HttpSession recoverNewSession(Object key)
+	{
+		if (_savedNewSessions == null)
+			return null;
+		return _savedNewSessions.get(key);
+	}
 
-        if (_authentication instanceof Authentication.User)
-            return ((Authentication.User)_authentication).isUserInRole(_scope,role);
-        return false;
-    }
-
-    /* ------------------------------------------------------------ */
-    public HttpSession recoverNewSession(Object key)
-    {
-        if (_savedNewSessions == null)
-            return null;
-        return _savedNewSessions.get(key);
-    }
+	/* ------------------------------------------------------------ */
+	protected void recycle()
+	{
+		if (_inputState == __READER)
+		{
+			try
+			{
+				int r = _reader.read();
+				while (r != -1)
+					r = _reader.read();
+			}
+			catch (Exception e)
+			{
+				LOG.ignore(e);
+				_reader = null;
+			}
+		}
 
-    /* ------------------------------------------------------------ */
-    protected void recycle()
-    {
-        if (_inputState == __READER)
-        {
-            try
-            {
-                int r = _reader.read();
-                while (r != -1)
-                    r = _reader.read();
-            }
-            catch (Exception e)
-            {
-                LOG.ignore(e);
-                _reader = null;
-            }
-        }
+		setAuthentication(Authentication.NOT_CHECKED);
+		_async.recycle();
+		_asyncSupported = true;
+		_handled = false;
+		if (_context != null)
+			throw new IllegalStateException("Request in context!");
+		if (_attributes != null)
+			_attributes.clearAttributes();
+		_characterEncoding = null;
+		_contextPath = null;
+		if (_cookies != null)
+			_cookies.reset();
+		_cookiesExtracted = false;
+		_context = null;
+		_serverName = null;
+		_method = null;
+		_pathInfo = null;
+		_port = 0;
+		_protocol = HttpVersions.HTTP_1_1;
+		_queryEncoding = null;
+		_queryString = null;
+		_requestedSessionId = null;
+		_requestedSessionIdFromCookie = false;
+		_session = null;
+		_requestURI = null;
+		_scope = null;
+		_scheme = URIUtil.HTTP;
+		_servletPath = null;
+		_timeStamp = 0;
+		_timeStampBuffer = null;
+		_uri = null;
+		if (_baseParameters != null)
+			_baseParameters.clear();
+		_parameters = null;
+		_paramsExtracted = false;
+		_inputState = __NONE;
 
-        setAuthentication(Authentication.NOT_CHECKED);
-        _async.recycle();
-        _asyncSupported = true;
-        _handled = false;
-        if (_context != null)
-            throw new IllegalStateException("Request in context!");
-        if (_attributes != null)
-            _attributes.clearAttributes();
-        _characterEncoding = null;
-        _contextPath = null;
-        if (_cookies != null)
-            _cookies.reset();
-        _cookiesExtracted = false;
-        _context = null;
-        _serverName = null;
-        _method = null;
-        _pathInfo = null;
-        _port = 0;
-        _protocol = HttpVersions.HTTP_1_1;
-        _queryEncoding = null;
-        _queryString = null;
-        _requestedSessionId = null;
-        _requestedSessionIdFromCookie = false;
-        _session = null;
-        _sessionManager = null;
-        _requestURI = null;
-        _scope = null;
-        _scheme = URIUtil.HTTP;
-        _servletPath = null;
-        _timeStamp = 0;
-        _timeStampBuffer = null;
-        _uri = null;
-        if (_baseParameters != null)
-            _baseParameters.clear();
-        _parameters = null;
-        _paramsExtracted = false;
-        _inputState = __NONE;
+		if (_savedNewSessions != null)
+			_savedNewSessions.clear();
+		_savedNewSessions=null;
+		_multiPartInputStream = null;
+	}
+
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
+	 */
+	public void removeAttribute(String name)
+	{
+		Object old_value = _attributes == null?null:_attributes.getAttribute(name);
 
-        if (_savedNewSessions != null)
-            _savedNewSessions.clear();
-        _savedNewSessions=null;
-        _multiPartInputStream = null;
-    }
+		if (_attributes != null)
+			_attributes.removeAttribute(name);
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
-     */
-    public void removeAttribute(String name)
-    {
-        Object old_value = _attributes == null?null:_attributes.getAttribute(name);
-
-        if (_attributes != null)
-            _attributes.removeAttribute(name);
+		if (old_value != null)
+		{
+			if (_requestAttributeListeners != null)
+			{
+				final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value);
+				final int size = LazyList.size(_requestAttributeListeners);
+				for (int i = 0; i < size; i++)
+				{
+					final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i);
+					if (listener instanceof ServletRequestAttributeListener)
+					{
+						final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener;
+						l.attributeRemoved(event);
+					}
+				}
+			}
+		}
+	}
 
-        if (old_value != null)
-        {
-            if (_requestAttributeListeners != null)
-            {
-                final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value);
-                final int size = LazyList.size(_requestAttributeListeners);
-                for (int i = 0; i < size; i++)
-                {
-                    final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i);
-                    if (listener instanceof ServletRequestAttributeListener)
-                    {
-                        final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener;
-                        l.attributeRemoved(event);
-                    }
-                }
-            }
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void removeEventListener(final EventListener listener)
+	{
+		_requestAttributeListeners = LazyList.remove(_requestAttributeListeners,listener);
+	}
+
+	/* ------------------------------------------------------------ */
+	public void saveNewSession(Object key, HttpSession session)
+	{
+		if (_savedNewSessions == null)
+			_savedNewSessions = new HashMap<Object, HttpSession>();
+		_savedNewSessions.put(key,session);
+	}
 
-    /* ------------------------------------------------------------ */
-    public void removeEventListener(final EventListener listener)
-    {
-        _requestAttributeListeners = LazyList.remove(_requestAttributeListeners,listener);
-    }
+	/* ------------------------------------------------------------ */
+	public void setAsyncSupported(boolean supported)
+	{
+		_asyncSupported = supported;
+	}
 
-    /* ------------------------------------------------------------ */
-    public void saveNewSession(Object key, HttpSession session)
-    {
-        if (_savedNewSessions == null)
-            _savedNewSessions = new HashMap<Object, HttpSession>();
-        _savedNewSessions.put(key,session);
-    }
-
-    /* ------------------------------------------------------------ */
-    public void setAsyncSupported(boolean supported)
-    {
-        _asyncSupported = supported;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to
+	 * {@link #setQueryEncoding}. <p> if the attribute name is "org.eclipse.jetty.server.server.ResponseBuffer", then the response buffer is flushed with @{link
+	 * #flushResponseBuffer} <p> if the attribute name is "org.eclipse.jetty.io.EndPoint.maxIdleTime", then the value is passed to the associated {@link
+	 * EndPoint#setMaxIdleTime}.
+	 *
+	 * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object)
+	 */
+	public void setAttribute(String name, Object value)
+	{
+		Object old_value = _attributes == null?null:_attributes.getAttribute(name);
 
-    /* ------------------------------------------------------------ */
-    /*
-     * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to
-     * {@link #setQueryEncoding}. <p> if the attribute name is "org.eclipse.jetty.server.server.ResponseBuffer", then the response buffer is flushed with @{link
-     * #flushResponseBuffer} <p> if the attribute name is "org.eclipse.jetty.io.EndPoint.maxIdleTime", then the value is passed to the associated {@link
-     * EndPoint#setMaxIdleTime}.
-     *
-     * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object)
-     */
-    public void setAttribute(String name, Object value)
-    {
-        Object old_value = _attributes == null?null:_attributes.getAttribute(name);
+		if (name.startsWith("org.eclipse.jetty."))
+		{
+			if ("org.eclipse.jetty.server.Request.queryEncoding".equals(name))
+				setQueryEncoding(value == null?null:value.toString());
+			else if ("org.eclipse.jetty.server.sendContent".equals(name))
+			{
+				try
+				{
+					((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value);
+				}
+				catch (IOException e)
+				{
+					throw new RuntimeException(e);
+				}
+			}
+			else if ("org.eclipse.jetty.server.ResponseBuffer".equals(name))
+			{
+				try
+				{
+					final ByteBuffer byteBuffer = (ByteBuffer)value;
+					synchronized (byteBuffer)
+					{
+						NIOBuffer buffer = byteBuffer.isDirect()?new DirectNIOBuffer(byteBuffer,true):new IndirectNIOBuffer(byteBuffer,true);
+						((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer);
+					}
+				}
+				catch (IOException e)
+				{
+					throw new RuntimeException(e);
+				}
+			}
+			else if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name))
+			{
+				try
+				{
+					getConnection().getEndPoint().setMaxIdleTime(Integer.valueOf(value.toString()));
+				}
+				catch (IOException e)
+				{
+					throw new RuntimeException(e);
+				}
+			}
+		}
 
-        if (name.startsWith("org.eclipse.jetty."))
-        {
-            if ("org.eclipse.jetty.server.Request.queryEncoding".equals(name))
-                setQueryEncoding(value == null?null:value.toString());
-            else if ("org.eclipse.jetty.server.sendContent".equals(name))
-            {
-                try
-                {
-                    ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value);
-                }
-                catch (IOException e)
-                {
-                    throw new RuntimeException(e);
-                }
-            }
-            else if ("org.eclipse.jetty.server.ResponseBuffer".equals(name))
-            {
-                try
-                {
-                    final ByteBuffer byteBuffer = (ByteBuffer)value;
-                    synchronized (byteBuffer)
-                    {
-                        NIOBuffer buffer = byteBuffer.isDirect()?new DirectNIOBuffer(byteBuffer,true):new IndirectNIOBuffer(byteBuffer,true);
-                        ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer);
-                    }
-                }
-                catch (IOException e)
-                {
-                    throw new RuntimeException(e);
-                }
-            }
-            else if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name))
-            {
-                try
-                {
-                    getConnection().getEndPoint().setMaxIdleTime(Integer.valueOf(value.toString()));
-                }
-                catch (IOException e)
-                {
-                    throw new RuntimeException(e);
-                }
-            }
-        }
+		if (_attributes == null)
+			_attributes = new AttributesMap();
+		_attributes.setAttribute(name,value);
+
+		if (_requestAttributeListeners != null)
+		{
+			final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value == null?value:old_value);
+			final int size = LazyList.size(_requestAttributeListeners);
+			for (int i = 0; i < size; i++)
+			{
+				final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i);
+				if (listener instanceof ServletRequestAttributeListener)
+				{
+					final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener;
 
-        if (_attributes == null)
-            _attributes = new AttributesMap();
-        _attributes.setAttribute(name,value);
-
-        if (_requestAttributeListeners != null)
-        {
-            final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value == null?value:old_value);
-            final int size = LazyList.size(_requestAttributeListeners);
-            for (int i = 0; i < size; i++)
-            {
-                final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i);
-                if (listener instanceof ServletRequestAttributeListener)
-                {
-                    final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener;
+					if (old_value == null)
+						l.attributeAdded(event);
+					else if (value == null)
+						l.attributeRemoved(event);
+					else
+						l.attributeReplaced(event);
+				}
+			}
+		}
+	}
 
-                    if (old_value == null)
-                        l.attributeAdded(event);
-                    else if (value == null)
-                        l.attributeRemoved(event);
-                    else
-                        l.attributeReplaced(event);
-                }
-            }
-        }
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 */
+	public void setAttributes(Attributes attributes)
+	{
+		_attributes = attributes;
+	}
+
+	/* ------------------------------------------------------------ */
 
-    /* ------------------------------------------------------------ */
-    /*
-     */
-    public void setAttributes(Attributes attributes)
-    {
-        _attributes = attributes;
-    }
-
-    /* ------------------------------------------------------------ */
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Set the authentication.
-     *
-     * @param authentication
-     *            the authentication to set
-     */
-    public void setAuthentication(Authentication authentication)
-    {
-        _authentication = authentication;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Set the authentication.
+	 *
+	 * @param authentication
+	 *            the authentication to set
+	 */
+	public void setAuthentication(Authentication authentication)
+	{
+		_authentication = authentication;
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
-     */
-    public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException
-    {
-        if (_inputState != __NONE)
-            return;
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
+	 */
+	public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException
+	{
+		if (_inputState != __NONE)
+			return;
 
-        _characterEncoding = encoding;
+		_characterEncoding = encoding;
 
-        // check encoding is supported
-        if (!StringUtil.isUTF8(encoding))
-            // noinspection ResultOfMethodCallIgnored
-            "".getBytes(encoding);
-    }
+		// check encoding is supported
+		if (!StringUtil.isUTF8(encoding))
+			// noinspection ResultOfMethodCallIgnored
+			"".getBytes(encoding);
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
-     */
-    public void setCharacterEncodingUnchecked(String encoding)
-    {
-        _characterEncoding = encoding;
-    }
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
+	 */
+	public void setCharacterEncodingUnchecked(String encoding)
+	{
+		_characterEncoding = encoding;
+	}
 
-    /* ------------------------------------------------------------ */
-    // final so we can safely call this from constructor
-    protected final void setConnection(AbstractHttpConnection connection)
-    {
-        _connection = connection;
-        _async.setConnection(connection);
-        _endp = connection.getEndPoint();
-        _dns = connection.getResolveNames();
-    }
+	/* ------------------------------------------------------------ */
+	// final so we can safely call this from constructor
+	protected final void setConnection(AbstractHttpConnection connection)
+	{
+		_connection = connection;
+		_async.setConnection(connection);
+		_endp = connection.getEndPoint();
+		_dns = connection.getResolveNames();
+	}
 
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.ServletRequest#getContentType()
-     */
-    public void setContentType(String contentType)
-    {
-        _connection.getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,contentType);
+	/* ------------------------------------------------------------ */
+	/*
+	 * @see javax.servlet.ServletRequest#getContentType()
+	 */
+	public void setContentType(String contentType)
+	{
+		_connection.getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,contentType);
 
-    }
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Set request context
-     *
-     * @param context
-     *            context object
-     */
-    public void setContext(Context context)
-    {
-        _newContext = _context != context;
-        _context = context;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Set request context
+	 *
+	 * @param context
+	 *            context object
+	 */
+	public void setContext(Context context)
+	{
+		_newContext = _context != context;
+		_context = context;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @return True if this is the first call of {@link #takeNewContext()} since the last
-     *         {@link #setContext(org.eclipse.jetty.server.handler.ContextHandler.Context)} call.
-     */
-    public boolean takeNewContext()
-    {
-        boolean nc = _newContext;
-        _newContext = false;
-        return nc;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @return True if this is the first call of {@link #takeNewContext()} since the last
+	 *         {@link #setContext(org.eclipse.jetty.server.handler.ContextHandler.Context)} call.
+	 */
+	public boolean takeNewContext()
+	{
+		boolean nc = _newContext;
+		_newContext = false;
+		return nc;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Sets the "context path" for this request
-     *
-     * @see HttpServletRequest#getContextPath()
-     */
-    public void setContextPath(String contextPath)
-    {
-        _contextPath = contextPath;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Sets the "context path" for this request
+	 *
+	 * @see HttpServletRequest#getContextPath()
+	 */
+	public void setContextPath(String contextPath)
+	{
+		_contextPath = contextPath;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param cookies
-     *            The cookies to set.
-     */
-    public void setCookies(Cookie[] cookies)
-    {
-        if (_cookies == null)
-            _cookies = new CookieCutter();
-        _cookies.setCookies(cookies);
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param cookies
+	 *            The cookies to set.
+	 */
+	public void setCookies(Cookie[] cookies)
+	{
+		if (_cookies == null)
+			_cookies = new CookieCutter();
+		_cookies.setCookies(cookies);
+	}
 
-    /* ------------------------------------------------------------ */
-    public void setDispatcherType(DispatcherType type)
-    {
-        _dispatcherType = type;
-    }
+	/* ------------------------------------------------------------ */
+	public void setDispatcherType(DispatcherType type)
+	{
+		_dispatcherType = type;
+	}
 
-    /* ------------------------------------------------------------ */
-    public void setHandled(boolean h)
-    {
-        _handled = h;
-    }
+	/* ------------------------------------------------------------ */
+	public void setHandled(boolean h)
+	{
+		_handled = h;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param method
-     *            The method to set.
-     */
-    public void setMethod(String method)
-    {
-        _method = method;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param method
+	 *            The method to set.
+	 */
+	public void setMethod(String method)
+	{
+		_method = method;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param parameters
-     *            The parameters to set.
-     */
-    public void setParameters(MultiMap<String> parameters)
-    {
-        _parameters = (parameters == null)?_baseParameters:parameters;
-        if (_paramsExtracted && _parameters == null)
-            throw new IllegalStateException();
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param parameters
+	 *            The parameters to set.
+	 */
+	public void setParameters(MultiMap<String> parameters)
+	{
+		_parameters = (parameters == null)?_baseParameters:parameters;
+		if (_paramsExtracted && _parameters == null)
+			throw new IllegalStateException();
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param pathInfo
-     *            The pathInfo to set.
-     */
-    public void setPathInfo(String pathInfo)
-    {
-        _pathInfo = pathInfo;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param pathInfo
+	 *            The pathInfo to set.
+	 */
+	public void setPathInfo(String pathInfo)
+	{
+		_pathInfo = pathInfo;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param protocol
-     *            The protocol to set.
-     */
-    public void setProtocol(String protocol)
-    {
-        _protocol = protocol;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param protocol
+	 *            The protocol to set.
+	 */
+	public void setProtocol(String protocol)
+	{
+		_protocol = protocol;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Set the character encoding used for the query string. This call will effect the return of getQueryString and getParamaters. It must be called before any
-     * geParameter methods.
-     *
-     * The request attribute "org.eclipse.jetty.server.server.Request.queryEncoding" may be set as an alternate method of calling setQueryEncoding.
-     *
-     * @param queryEncoding
-     */
-    public void setQueryEncoding(String queryEncoding)
-    {
-        _queryEncoding = queryEncoding;
-        _queryString = null;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Set the character encoding used for the query string. This call will effect the return of getQueryString and getParamaters. It must be called before any
+	 * geParameter methods.
+	 *
+	 * The request attribute "org.eclipse.jetty.server.server.Request.queryEncoding" may be set as an alternate method of calling setQueryEncoding.
+	 *
+	 * @param queryEncoding
+	 */
+	public void setQueryEncoding(String queryEncoding)
+	{
+		_queryEncoding = queryEncoding;
+		_queryString = null;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param queryString
-     *            The queryString to set.
-     */
-    public void setQueryString(String queryString)
-    {
-        _queryString = queryString;
-        _queryEncoding = null; //assume utf-8
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param queryString
+	 *            The queryString to set.
+	 */
+	public void setQueryString(String queryString)
+	{
+		_queryString = queryString;
+		_queryEncoding = null; //assume utf-8
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param addr
-     *            The address to set.
-     */
-    public void setRemoteAddr(String addr)
-    {
-        _remoteAddr = addr;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param addr
+	 *            The address to set.
+	 */
+	public void setRemoteAddr(String addr)
+	{
+		_remoteAddr = addr;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param host
-     *            The host to set.
-     */
-    public void setRemoteHost(String host)
-    {
-        _remoteHost = host;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param host
+	 *            The host to set.
+	 */
+	public void setRemoteHost(String host)
+	{
+		_remoteHost = host;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param requestedSessionId
-     *            The requestedSessionId to set.
-     */
-    public void setRequestedSessionId(String requestedSessionId)
-    {
-        _requestedSessionId = requestedSessionId;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param requestedSessionId
+	 *            The requestedSessionId to set.
+	 */
+	public void setRequestedSessionId(String requestedSessionId)
+	{
+		_requestedSessionId = requestedSessionId;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param requestedSessionIdCookie
-     *            The requestedSessionIdCookie to set.
-     */
-    public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie)
-    {
-        _requestedSessionIdFromCookie = requestedSessionIdCookie;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param requestedSessionIdCookie
+	 *            The requestedSessionIdCookie to set.
+	 */
+	public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie)
+	{
+		_requestedSessionIdFromCookie = requestedSessionIdCookie;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param requestURI
-     *            The requestURI to set.
-     */
-    public void setRequestURI(String requestURI)
-    {
-        _requestURI = requestURI;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param requestURI
+	 *            The requestURI to set.
+	 */
+	public void setRequestURI(String requestURI)
+	{
+		_requestURI = requestURI;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param scheme
-     *            The scheme to set.
-     */
-    public void setScheme(String scheme)
-    {
-        _scheme = scheme;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param scheme
+	 *            The scheme to set.
+	 */
+	public void setScheme(String scheme)
+	{
+		_scheme = scheme;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param host
-     *            The host to set.
-     */
-    public void setServerName(String host)
-    {
-        _serverName = host;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param host
+	 *            The host to set.
+	 */
+	public void setServerName(String host)
+	{
+		_serverName = host;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param port
-     *            The port to set.
-     */
-    public void setServerPort(int port)
-    {
-        _port = port;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param port
+	 *            The port to set.
+	 */
+	public void setServerPort(int port)
+	{
+		_port = port;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param servletPath
-     *            The servletPath to set.
-     */
-    public void setServletPath(String servletPath)
-    {
-        _servletPath = servletPath;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param servletPath
+	 *            The servletPath to set.
+	 */
+	public void setServletPath(String servletPath)
+	{
+		_servletPath = servletPath;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param session
-     *            The session to set.
-     */
-    public void setSession(HttpSession session)
-    {
-        _session = session;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param session
+	 *            The session to set.
+	 */
+	public void setSession(HttpSession session)
+	{
+		_session = session;
+	}
+
+	/* ------------------------------------------------------------ */
+	public void setTimeStamp(long ts)
+	{
+		_timeStamp = ts;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param sessionManager
-     *            The sessionManager to set.
-     */
-    public void setSessionManager(SessionManager sessionManager)
-    {
-        _sessionManager = sessionManager;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void setTimeStamp(long ts)
-    {
-        _timeStamp = ts;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * @param uri
+	 *            The uri to set.
+	 */
+	public void setUri(HttpURI uri)
+	{
+		_uri = uri;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * @param uri
-     *            The uri to set.
-     */
-    public void setUri(HttpURI uri)
-    {
-        _uri = uri;
-    }
+	/* ------------------------------------------------------------ */
+	public void setUserIdentityScope(UserIdentity.Scope scope)
+	{
+		_scope = scope;
+	}
 
-    /* ------------------------------------------------------------ */
-    public void setUserIdentityScope(UserIdentity.Scope scope)
-    {
-        _scope = scope;
-    }
+	/* ------------------------------------------------------------ */
+	/**
+	 * Set timetstamp of request dispatch
+	 *
+	 * @param value
+	 *            timestamp
+	 */
+	public void setDispatchTime(long value)
+	{
+		_dispatchTime = value;
+	}
 
-    /* ------------------------------------------------------------ */
-    /**
-     * Set timetstamp of request dispatch
-     *
-     * @param value
-     *            timestamp
-     */
-    public void setDispatchTime(long value)
-    {
-        _dispatchTime = value;
-    }
+	/* ------------------------------------------------------------ */
+	public AsyncContext startAsync() throws IllegalStateException
+	{
+		if (!_asyncSupported)
+			throw new IllegalStateException("!asyncSupported");
+		_async.startAsync();
+		return _async;
+	}
+
+	/* ------------------------------------------------------------ */
+	public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException
+	{
+		if (!_asyncSupported)
+			throw new IllegalStateException("!asyncSupported");
+		_async.startAsync(_context,servletRequest,servletResponse);
+		return _async;
+	}
 
-    /* ------------------------------------------------------------ */
-    public AsyncContext startAsync() throws IllegalStateException
-    {
-        if (!_asyncSupported)
-            throw new IllegalStateException("!asyncSupported");
-        _async.startAsync();
-        return _async;
-    }
+	/* ------------------------------------------------------------ */
+	@Override
+	public String toString()
+	{
+		return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString();
+	}
 
-    /* ------------------------------------------------------------ */
-    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException
-    {
-        if (!_asyncSupported)
-            throw new IllegalStateException("!asyncSupported");
-        _async.startAsync(_context,servletRequest,servletResponse);
-        return _async;
-    }
+	/* ------------------------------------------------------------ */
+	public boolean authenticate(HttpServletResponse response) throws IOException, ServletException
+	{
+		if (_authentication instanceof Authentication.Deferred)
+		{
+			setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response));
+			return !(_authentication instanceof Authentication.ResponseSent);        
+		}
+		response.sendError(HttpStatus.UNAUTHORIZED_401);
+		return false;
+	}
 
-    /* ------------------------------------------------------------ */
-    @Override
-    public String toString()
-    {
-        return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString();
-    }
+	/* ------------------------------------------------------------ */
+	public Part getPart(String name) throws IOException, ServletException
+	{                
+		getParts();
+		return _multiPartInputStream.getPart(name);
+	}
 
-    /* ------------------------------------------------------------ */
-    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException
-    {
-        if (_authentication instanceof Authentication.Deferred)
-        {
-            setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response));
-            return !(_authentication instanceof Authentication.ResponseSent);        
-        }
-        response.sendError(HttpStatus.UNAUTHORIZED_401);
-        return false;
-    }
-
-    /* ------------------------------------------------------------ */
-    public Part getPart(String name) throws IOException, ServletException
-    {                
-        getParts();
-        return _multiPartInputStream.getPart(name);
-    }
+	/* ------------------------------------------------------------ */
+	public Collection<Part> getParts() throws IOException, ServletException
+	{
+		if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
+			throw new ServletException("Content-Type != multipart/form-data");
+		
+		if (_multiPartInputStream == null)
+			_multiPartInputStream = (MultiPartInputStream)getAttribute(__MULTIPART_INPUT_STREAM);
+		
+		if (_multiPartInputStream == null)
+		{
+			MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
+			
+			if (config == null)
+				throw new IllegalStateException("No multipart config for servlet");
+			
+			_multiPartInputStream = new MultiPartInputStream(getInputStream(), 
+															 getContentType(), config, 
+															 (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null));
+			
+			setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream);
+			setAttribute(__MULTIPART_CONTEXT, _context);
+			Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing 
+			for (Part p:parts)
+			{
+				MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p;
+				if (mp.getContentDispositionFilename() == null)
+				{
+					//Servlet Spec 3.0 pg 23, parts without filenames must be put into init params
+					String charset = null;
+					if (mp.getContentType() != null)
+						charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType()));
 
-    /* ------------------------------------------------------------ */
-    public Collection<Part> getParts() throws IOException, ServletException
-    {
-        if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
-            throw new ServletException("Content-Type != multipart/form-data");
-        
-        if (_multiPartInputStream == null)
-            _multiPartInputStream = (MultiPartInputStream)getAttribute(__MULTIPART_INPUT_STREAM);
-        
-        if (_multiPartInputStream == null)
-        {
-            MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
-            
-            if (config == null)
-                throw new IllegalStateException("No multipart config for servlet");
-            
-            _multiPartInputStream = new MultiPartInputStream(getInputStream(), 
-                                                             getContentType(), config, 
-                                                             (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null));
-            
-            setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream);
-            setAttribute(__MULTIPART_CONTEXT, _context);
-            Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing 
-            for (Part p:parts)
-            {
-                MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p;
-                if (mp.getContentDispositionFilename() == null)
-                {
-                    //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params
-                    String charset = null;
-                    if (mp.getContentType() != null)
-                        charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType()));
+					ByteArrayOutputStream os = null;
+					InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file
+					try
+					{
+						os = new ByteArrayOutputStream();
+						IO.copy(is, os);
+						String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset);   
+						getParameter(""); //cause params to be evaluated
+						getParameters().add(mp.getName(), content);
+					}
+					finally
+					{
+						IO.close(os);
+						IO.close(is);
+					}
+				}
+			}
+		}
+
+		return _multiPartInputStream.getParts();
+	}
 
-                    ByteArrayOutputStream os = null;
-                    InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file
-                    try
-                    {
-                        os = new ByteArrayOutputStream();
-                        IO.copy(is, os);
-                        String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset);   
-                        getParameter(""); //cause params to be evaluated
-                        getParameters().add(mp.getName(), content);
-                    }
-                    finally
-                    {
-                        IO.close(os);
-                        IO.close(is);
-                    }
-                }
-            }
-        }
-
-        return _multiPartInputStream.getParts();
-    }
+	/* ------------------------------------------------------------ */
+	public void login(String username, String password) throws ServletException
+	{
+		if (_authentication instanceof Authentication.Deferred) 
+		{
+			_authentication=((Authentication.Deferred)_authentication).login(username,password,this);
+			if (_authentication == null)
+				throw new ServletException();
+		} 
+		else 
+		{
+			throw new ServletException("Authenticated as "+_authentication);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    public void login(String username, String password) throws ServletException
-    {
-        if (_authentication instanceof Authentication.Deferred) 
-        {
-            _authentication=((Authentication.Deferred)_authentication).login(username,password,this);
-            if (_authentication == null)
-                throw new ServletException();
-        } 
-        else 
-        {
-            throw new ServletException("Authenticated as "+_authentication);
-        }
-    }
+	/* ------------------------------------------------------------ */
+	public void logout() throws ServletException
+	{
+		if (_authentication instanceof Authentication.User)
+			((Authentication.User)_authentication).logout();
+		_authentication=Authentication.UNAUTHENTICATED;
+	}
+	
+	/* ------------------------------------------------------------ */
+	/**
+	 * Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and
+	 * {@link #setQueryString(String)} are called with the result. The merge is according to the rules of the servlet dispatch forward method.
+	 *
+	 * @param query
+	 *            The query string to merge into the request.
+	 */
+	public void mergeQueryString(String query)
+	{
+		// extract parameters from dispatch query
+		MultiMap<String> parameters = new MultiMap<String>();
+		UrlEncoded.decodeTo(query,parameters, StringUtil.__UTF8); //have to assume UTF-8 because we can't know otherwise
 
-    /* ------------------------------------------------------------ */
-    public void logout() throws ServletException
-    {
-        if (_authentication instanceof Authentication.User)
-            ((Authentication.User)_authentication).logout();
-        _authentication=Authentication.UNAUTHENTICATED;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and
-     * {@link #setQueryString(String)} are called with the result. The merge is according to the rules of the servlet dispatch forward method.
-     *
-     * @param query
-     *            The query string to merge into the request.
-     */
-    public void mergeQueryString(String query)
-    {
-        // extract parameters from dispatch query
-        MultiMap<String> parameters = new MultiMap<String>();
-        UrlEncoded.decodeTo(query,parameters, StringUtil.__UTF8); //have to assume UTF-8 because we can't know otherwise
+		boolean merge_old_query = false;
 
-        boolean merge_old_query = false;
+		// Have we evaluated parameters
+		if (!_paramsExtracted)
+			extractParameters();
 
-        // Have we evaluated parameters
-        if (!_paramsExtracted)
-            extractParameters();
+		// Are there any existing parameters?
+		if (_parameters != null && _parameters.size() > 0)
+		{
+			// Merge parameters; new parameters of the same name take precedence.
+			Iterator<Entry<String, Object>> iter = _parameters.entrySet().iterator();
+			while (iter.hasNext())
+			{
+				Map.Entry<String, Object> entry = iter.next();
+				String name = entry.getKey();
 
-        // Are there any existing parameters?
-        if (_parameters != null && _parameters.size() > 0)
-        {
-            // Merge parameters; new parameters of the same name take precedence.
-            Iterator<Entry<String, Object>> iter = _parameters.entrySet().iterator();
-            while (iter.hasNext())
-            {
-                Map.Entry<String, Object> entry = iter.next();
-                String name = entry.getKey();
+				// If the names match, we will need to remake the query string
+				if (parameters.containsKey(name))
+					merge_old_query = true;
 
-                // If the names match, we will need to remake the query string
-                if (parameters.containsKey(name))
-                    merge_old_query = true;
-
-                // Add the old values to the new parameter map
-                Object values = entry.getValue();
-                for (int i = 0; i < LazyList.size(values); i++)
-                    parameters.add(name,LazyList.get(values,i));
-            }
-        }
+				// Add the old values to the new parameter map
+				Object values = entry.getValue();
+				for (int i = 0; i < LazyList.size(values); i++)
+					parameters.add(name,LazyList.get(values,i));
+			}
+		}
 
-        if (_queryString != null && _queryString.length() > 0)
-        {
-            if (merge_old_query)
-            {
-                StringBuilder overridden_query_string = new StringBuilder();
-                MultiMap<String> overridden_old_query = new MultiMap<String>();
-                UrlEncoded.decodeTo(_queryString,overridden_old_query,getQueryEncoding());//decode using any queryencoding set for the request
-                
-                
-                MultiMap<String> overridden_new_query = new MultiMap<String>();
-                UrlEncoded.decodeTo(query,overridden_new_query,StringUtil.__UTF8); //have to assume utf8 as we cannot know otherwise
+		if (_queryString != null && _queryString.length() > 0)
+		{
+			if (merge_old_query)
+			{
+				StringBuilder overridden_query_string = new StringBuilder();
+				MultiMap<String> overridden_old_query = new MultiMap<String>();
+				UrlEncoded.decodeTo(_queryString,overridden_old_query,getQueryEncoding());//decode using any queryencoding set for the request
+				
+				
+				MultiMap<String> overridden_new_query = new MultiMap<String>();
+				UrlEncoded.decodeTo(query,overridden_new_query,StringUtil.__UTF8); //have to assume utf8 as we cannot know otherwise
 
-                Iterator<Entry<String, Object>> iter = overridden_old_query.entrySet().iterator();
-                while (iter.hasNext())
-                {
-                    Map.Entry<String, Object> entry = iter.next();
-                    String name = entry.getKey();
-                    if (!overridden_new_query.containsKey(name))
-                    {
-                        Object values = entry.getValue();
-                        for (int i = 0; i < LazyList.size(values); i++)
-                        {
-                            overridden_query_string.append("&").append(name).append("=").append((Object)LazyList.get(values,i));
-                        }
-                    }
-                }
+				Iterator<Entry<String, Object>> iter = overridden_old_query.entrySet().iterator();
+				while (iter.hasNext())
+				{
+					Map.Entry<String, Object> entry = iter.next();
+					String name = entry.getKey();
+					if (!overridden_new_query.containsKey(name))
+					{
+						Object values = entry.getValue();
+						for (int i = 0; i < LazyList.size(values); i++)
+						{
+							overridden_query_string.append("&").append(name).append("=").append((Object)LazyList.get(values,i));
+						}
+					}
+				}
 
-                query = query + overridden_query_string;
-            }
-            else
-            {
-                query = query + "&" + _queryString;
-            }
-        }
+				query = query + overridden_query_string;
+			}
+			else
+			{
+				query = query + "&" + _queryString;
+			}
+		}
 
-        setParameters(parameters);
-        setQueryString(query);
-    }
+		setParameters(parameters);
+		setQueryString(query);
+	}
 }
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/Response.java
--- a/src/org/eclipse/jetty/server/Response.java	Thu Sep 08 16:13:27 2016 -0600
+++ b/src/org/eclipse/jetty/server/Response.java	Thu Sep 08 16:38:30 2016 -0600
@@ -187,96 +187,7 @@
      */
     public String encodeURL(String url)
     {
-        final Request request=_connection.getRequest();
-        SessionManager sessionManager = request.getSessionManager();
-        if (sessionManager==null)
-            return url;
-        
-        HttpURI uri = null;
-        if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url))
-        {
-            uri = new HttpURI(url);
-            String path = uri.getPath();
-            path = (path == null?"":path);
-            int port=uri.getPort();
-            if (port<0) 
-                port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80;
-            if (!request.getServerName().equalsIgnoreCase(uri.getHost()) ||
-                request.getServerPort()!=port ||
-                !path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts
-                return url;
-        }
-        
-        String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix();
-        if (sessionURLPrefix==null)
-            return url;
-
-        if (url==null)
-            return null;
-        
-        // should not encode if cookies in evidence
-        if ((sessionManager.isUsingCookies() && request.isRequestedSessionIdFromCookie()) || !sessionManager.isUsingURLs()) 
-        {
-            int prefix=url.indexOf(sessionURLPrefix);
-            if (prefix!=-1)
-            {
-                int suffix=url.indexOf("?",prefix);
-                if (suffix<0)
-                    suffix=url.indexOf("#",prefix);
-
-                if (suffix<=prefix)
-                    return url.substring(0,prefix);
-                return url.substring(0,prefix)+url.substring(suffix);
-            }
-            return url;
-        }
-
-        // get session;
-        HttpSession session=request.getSession(false);
-
-        // no session
-        if (session == null)
-            return url;
-
-        // invalid session
-        if (!sessionManager.isValid(session))
-            return url;
-
-        String id=sessionManager.getNodeId(session);
-
-        if (uri == null)
-                uri = new HttpURI(url);
-     
-        
-        // Already encoded
-        int prefix=url.indexOf(sessionURLPrefix);
-        if (prefix!=-1)
-        {
-            int suffix=url.indexOf("?",prefix);
-            if (suffix<0)
-                suffix=url.indexOf("#",prefix);
-
-            if (suffix<=prefix)
-                return url.substring(0,prefix+sessionURLPrefix.length())+id;
-            return url.substring(0,prefix+sessionURLPrefix.length())+id+
-                url.substring(suffix);
-        }
-
-        // edit the session
-        int suffix=url.indexOf('?');
-        if (suffix<0)
-            suffix=url.indexOf('#');
-        if (suffix<0) 
-        {          
-            return url+ 
-                   ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path
-                   sessionURLPrefix+id;
-        }
-     
-        
-        return url.substring(0,suffix)+
-            ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path
-            sessionURLPrefix+id+url.substring(suffix);
+		throw new UnsupportedOperationException();
     }
 
     /* ------------------------------------------------------------ */
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/SessionManager.java
--- a/src/org/eclipse/jetty/server/SessionManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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;
-
-import java.util.EventListener;
-import java.util.Set;
-
-import javax.servlet.SessionCookieConfig;
-import javax.servlet.SessionTrackingMode;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.eclipse.jetty.http.HttpCookie;
-import org.eclipse.jetty.server.session.SessionHandler;
-import org.eclipse.jetty.util.component.LifeCycle;
-
-/* --------------------------------------------------------------------- */
-/**
- * Session Manager.
- * The API required to manage sessions for a servlet context.
- *
- */
-
-/* ------------------------------------------------------------ */
-/**
- */
-public interface SessionManager extends LifeCycle
-{
-    /* ------------------------------------------------------------ */
-    /**
-     * Session cookie name.
-     * Defaults to <code>JSESSIONID</code>, but can be set with the
-     * <code>org.eclipse.jetty.servlet.SessionCookie</code> context init parameter.
-     */
-    public final static String __SessionCookieProperty = "org.eclipse.jetty.servlet.SessionCookie";
-    public final static String __DefaultSessionCookie = "JSESSIONID";
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Session id path parameter name.
-     * Defaults to <code>jsessionid</code>, but can be set with the
-     * <code>org.eclipse.jetty.servlet.SessionIdPathParameterName</code> context init parameter.
-     * If set to null or "none" no URL rewriting will be done.
-     */
-    public final static String __SessionIdPathParameterNameProperty = "org.eclipse.jetty.servlet.SessionIdPathParameterName";
-    public final static String __DefaultSessionIdPathParameterName = "jsessionid";
-    public final static String __CheckRemoteSessionEncoding = "org.eclipse.jetty.servlet.CheckingRemoteSessionIdEncoding";
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Session Domain.
-     * If this property is set as a ServletContext InitParam, then it is
-     * used as the domain for session cookies. If it is not set, then
-     * no domain is specified for the session cookie.
-     */
-    public final static String __SessionDomainProperty = "org.eclipse.jetty.servlet.SessionDomain";
-    public final static String __DefaultSessionDomain = null;
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Session Path.
-     * If this property is set as a ServletContext InitParam, then it is
-     * used as the path for the session cookie.  If it is not set, then
-     * the context path is used as the path for the cookie.
-     */
-    public final static String __SessionPathProperty = "org.eclipse.jetty.servlet.SessionPath";
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Session Max Age.
-     * If this property is set as a ServletContext InitParam, then it is
-     * used as the max age for the session cookie.  If it is not set, then
-     * a max age of -1 is used.
-     */
-    public final static String __MaxAgeProperty = "org.eclipse.jetty.servlet.MaxAge";
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Returns the <code>HttpSession</code> with the given session id
-     *
-     * @param id the session id
-     * @return the <code>HttpSession</code> with the corresponding id or null if no session with the given id exists
-     */
-    public HttpSession getHttpSession(String id);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Creates a new <code>HttpSession</code>.
-     *
-     * @param request the HttpServletRequest containing the requested session id
-     * @return the new <code>HttpSession</code>
-     */
-    public HttpSession newHttpSession(HttpServletRequest request);
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true if session cookies should be HTTP-only (Microsoft extension)
-     * @see org.eclipse.jetty.http.HttpCookie#isHttpOnly()
-     */
-    public boolean getHttpOnly();
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the max period of inactivity, after which the session is invalidated, in seconds.
-     * @see #setMaxInactiveInterval(int)
-     */
-    public int getMaxInactiveInterval();
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Sets the max period of inactivity, after which the session is invalidated, in seconds.
-     *
-     * @param seconds the max inactivity period, in seconds.
-     * @see #getMaxInactiveInterval()
-     */
-    public void setMaxInactiveInterval(int seconds);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Sets the {@link SessionHandler}.
-     *
-     * @param handler the <code>SessionHandler</code> object
-     */
-    public void setSessionHandler(SessionHandler handler);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Adds an event listener for session-related events.
-     *
-     * @param listener the session event listener to add
-     *                 Individual SessionManagers implementations may accept arbitrary listener types,
-     *                 but they are expected to at least handle HttpSessionActivationListener,
-     *                 HttpSessionAttributeListener, HttpSessionBindingListener and HttpSessionListener.
-     * @see #removeEventListener(EventListener)
-     */
-    public void addEventListener(EventListener listener);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Removes an event listener for for session-related events.
-     *
-     * @param listener the session event listener to remove
-     * @see #addEventListener(EventListener)
-     */
-    public void removeEventListener(EventListener listener);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Removes all event listeners for session-related events.
-     *
-     * @see #removeEventListener(EventListener)
-     */
-    public void clearEventListeners();
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Gets a Cookie for a session.
-     *
-     * @param session         the session to which the cookie should refer.
-     * @param contextPath     the context to which the cookie should be linked.
-     *                        The client will only send the cookie value when requesting resources under this path.
-     * @param requestIsSecure whether the client is accessing the server over a secure protocol (i.e. HTTPS).
-     * @return if this <code>SessionManager</code> uses cookies, then this method will return a new
-     *         {@link Cookie cookie object} that should be set on the client in order to link future HTTP requests
-     *         with the <code>session</code>. If cookies are not in use, this method returns <code>null</code>.
-     */
-    public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the cross context session id manager.
-     * @see #setSessionIdManager(SessionIdManager)
-     */
-    public SessionIdManager getSessionIdManager();
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the cross context session id manager.
-     * @deprecated use {@link #getSessionIdManager()}
-     */
-    @Deprecated
-    public SessionIdManager getMetaManager();
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Sets the cross context session id manager
-     *
-     * @param idManager the cross context session id manager.
-     * @see #getSessionIdManager()
-     */
-    public void setSessionIdManager(SessionIdManager idManager);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param session the session to test for validity
-     * @return whether the given session is valid, that is, it has not been invalidated.
-     */
-    public boolean isValid(HttpSession session);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param session the session object
-     * @return the unique id of the session within the cluster, extended with an optional node id.
-     * @see #getClusterId(HttpSession)
-     */
-    public String getNodeId(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)
-     */
-    public String getClusterId(HttpSession session);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Called by the {@link SessionHandler} when a session is first accessed by a request.
-     *
-     * @param session the session object
-     * @param secure  whether the request is secure or not
-     * @return the session cookie. If not null, this cookie should be set on the response to either migrate
-     *         the session or to refresh a session cookie that may expire.
-     * @see #complete(HttpSession)
-     */
-    public HttpCookie access(HttpSession session, boolean secure);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Called by the {@link SessionHandler} when a session is last accessed by a request.
-     *
-     * @param session the session object
-     * @see #access(HttpSession, boolean)
-     */
-    public void complete(HttpSession session);
-
-    /**
-     * Sets the session id URL path parameter name.
-     *
-     * @param parameterName the URL path parameter name for session id URL rewriting (null or "none" for no rewriting).
-     * @see #getSessionIdPathParameterName()
-     * @see #getSessionIdPathParameterNamePrefix()
-     */
-    public void setSessionIdPathParameterName(String parameterName);
-
-    /**
-     * @return the URL path parameter name for session id URL rewriting, by default "jsessionid".
-     * @see #setSessionIdPathParameterName(String)
-     */
-    public String getSessionIdPathParameterName();
-
-    /**
-     * @return a formatted version of {@link #getSessionIdPathParameterName()}, by default
-     *         ";" + sessionIdParameterName + "=", for easier lookup in URL strings.
-     * @see #getSessionIdPathParameterName()
-     */
-    public String getSessionIdPathParameterNamePrefix();
-
-    /**
-     * @return whether the session management is handled via cookies.
-     */
-    public boolean isUsingCookies();
-    
-    /**
-     * @return whether the session management is handled via URLs.
-     */
-    public boolean isUsingURLs();
-
-    public Set<SessionTrackingMode> getDefaultSessionTrackingModes();
-
-    public Set<SessionTrackingMode> getEffectiveSessionTrackingModes();
-
-    public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes);
-
-    public SessionCookieConfig getSessionCookieConfig();
-    
-    /**
-     * @return True if absolute URLs are check for remoteness before being session encoded.
-     */
-    public boolean isCheckingRemoteSessionIdEncoding();
-    
-    /**
-     * @param remote True if absolute URLs are check for remoteness before being session encoded.
-     */
-    public void setCheckingRemoteSessionIdEncoding(boolean remote);
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/AbstractSession.java
--- a/src/org/eclipse/jetty/server/session/AbstractSession.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,568 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.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.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;
-    
-    private final AbstractSessionManager _manager;
-    private final String _clusterId; // ID unique within cluster
-    private final String _nodeId;    // ID unique within node
-    private final Map<String,Object> _attributes=new HashMap<String, Object>();
-    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
-     */
-    protected void checkValid() throws IllegalStateException
-    {
-        if (_invalid)
-            throw new IllegalStateException();
-    }
-    
-    /* ------------------------------------------------------------- */
-    public AbstractSession getSession()
-    {
-        return this;
-    }
-
-    /* ------------------------------------------------------------- */
-    public long getAccessed()
-    {
-        synchronized (this)
-        {
-            return _accessed;
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    public Object getAttribute(String name)
-    {
-        synchronized (this)
-        {
-            checkValid();
-            return _attributes.get(name);
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    public int getAttributes()
-    {
-        synchronized (this)
-        {
-            checkValid();
-            return _attributes.size();
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @SuppressWarnings({ "unchecked" })
-    public Enumeration<String> getAttributeNames()
-    {
-        synchronized (this)
-        {
-            checkValid();
-            List<String> names=_attributes==null?Collections.EMPTY_LIST:new ArrayList<String>(_attributes.keySet());
-            return Collections.enumeration(names);
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    public Set<String> getNames()
-    {
-        synchronized (this)
-        { 
-            return new HashSet<String>(_attributes.keySet());
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    public long getCookieSetTime()
-    {
-        return _cookieSet;
-    }
-
-    /* ------------------------------------------------------------- */
-    public long getCreationTime() throws IllegalStateException
-    {
-        return _created;
-    }
-
-    /* ------------------------------------------------------------ */
-    public String getId() throws IllegalStateException
-    {
-        return _manager._nodeIdInSessionId?_nodeId:_clusterId;
-    }
-
-    /* ------------------------------------------------------------- */
-    public String getNodeId()
-    {
-        return _nodeId;
-    }
-
-    /* ------------------------------------------------------------- */
-    public String getClusterId()
-    {
-        return _clusterId;
-    }
-
-    /* ------------------------------------------------------------- */
-    public long getLastAccessedTime() throws IllegalStateException
-    {
-        checkValid();
-        return _lastAccessed;
-    }
-    
-    /* ------------------------------------------------------------- */
-    public void setLastAccessedTime(long time)
-    {
-        _lastAccessed = time;
-    }
-
-    /* ------------------------------------------------------------- */
-    public int getMaxInactiveInterval()
-    {
-        checkValid();
-        return (int)(_maxIdleMs/1000);
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see javax.servlet.http.HttpSession#getServletContext()
-     */
-    public ServletContext getServletContext()
-    {
-        return _manager._context;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Deprecated
-    public HttpSessionContext getSessionContext() throws IllegalStateException
-    {
-        checkValid();
-        return AbstractSessionManager.__nullSessionContext;
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #getAttribute}
-     */
-    @Deprecated
-    public Object getValue(String name) throws IllegalStateException
-    {
-        return getAttribute(name);
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #getAttributeNames}
-     */
-    @Deprecated
-    public String[] getValueNames() throws IllegalStateException
-    {
-        synchronized(this)
-        {
-            checkValid();
-            if (_attributes==null)
-                return new String[0];
-            String[] a=new String[_attributes.size()];
-            return (String[])_attributes.keySet().toArray(a);
-        }
-    }
-    
-    /* ------------------------------------------------------------ */
-    protected  Map<String,Object> getAttributeMap ()
-    {
-        return _attributes;
-    }
-    
-    /* ------------------------------------------------------------ */
-    protected void addAttributes(Map<String,Object> map)
-    {
-        _attributes.putAll(map);
-    }
-
-    /* ------------------------------------------------------------ */
-    protected boolean access(long time)
-    {
-        synchronized(this)
-        {
-            if (_invalid)
-                return false;
-            _newSession=false;
-            _lastAccessed=_accessed;
-            _accessed=time;
-
-            if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < 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();
-    }
-
-    /* ------------------------------------------------------------- */
-    public void invalidate() throws IllegalStateException
-    {
-        // remove session from context and invalidate other sessions with same ID.
-        _manager.removeSession(this,true);
-        doInvalidate();
-    }
-
-    /* ------------------------------------------------------------- */
-    protected void doInvalidate() throws IllegalStateException
-    {
-        try
-        {
-            LOG.debug("invalidate {}",_clusterId);
-            if (isValid())
-                clearAttributes();
-        }
-        finally
-        {
-            synchronized (this)
-            {
-                // mark as invalid
-                _invalid=true;
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    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);
-
-                _manager.doSessionAttributeListeners(this,key,value,null);
-            }
-        } 
-        if (_attributes!=null)
-            _attributes.clear();
-    }
-    
-    /* ------------------------------------------------------------- */
-    public boolean isIdChanged()
-    {
-        return _idChanged;
-    }
-
-    /* ------------------------------------------------------------- */
-    public boolean isNew() throws IllegalStateException
-    {
-        checkValid();
-        return _newSession;
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #setAttribute}
-     */
-    @Deprecated
-    public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
-    {
-        setAttribute(name,value);
-    }
-
-    /* ------------------------------------------------------------ */
-    public void removeAttribute(String name)
-    {
-        setAttribute(name,null);
-    }
-
-    /* ------------------------------------------------------------- */
-    /**
-     * @deprecated As of Version 2.2, this method is replaced by
-     *             {@link #removeAttribute}
-     */
-    @Deprecated
-    public void removeValue(java.lang.String name) throws IllegalStateException
-    {
-        removeAttribute(name);
-    }
-
-    /* ------------------------------------------------------------ */
-    protected Object doPutOrRemove(String name, Object value)
-    {
-        return value==null?_attributes.remove(name):_attributes.put(name,value);
-    }
-
-    /* ------------------------------------------------------------ */
-    protected Object doGet(String name)
-    {
-        return _attributes.get(name);
-    }
-    
-    /* ------------------------------------------------------------ */
-    public void setAttribute(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);
-            
-        }
-    }
-
-    /* ------------------------------------------------------------- */
-    public void setIdChanged(boolean changed)
-    {
-        _idChanged=changed;
-    }
-
-    /* ------------------------------------------------------------- */
-    public void setMaxInactiveInterval(int secs)
-    {
-        _maxIdleMs=(long)secs*1000L;
-    }
-
-    /* ------------------------------------------------------------- */
-    @Override
-    public String toString()
-    {
-        return this.getClass().getName()+":"+getId()+"@"+hashCode();
-    }
-
-    /* ------------------------------------------------------------- */
-    /** If value implements HttpSessionBindingListener, call valueBound() */
-    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;
-        }
-    }
-    
-    /* ------------------------------------------------------------- */
-    /** If value implements HttpSessionBindingListener, call valueUnbound() */
-    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 = _attributes.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 = _attributes.values().iterator(); iter.hasNext();)
-            {
-                Object value = iter.next();
-                if (value instanceof HttpSessionActivationListener)
-                {
-                    HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
-                    listener.sessionDidActivate(event);
-                }
-            }
-        }
-    }
-    
-    
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/AbstractSessionIdManager.java
--- a/src/org/eclipse/jetty/server/session/AbstractSessionIdManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.security.SecureRandom;
-import java.util.Random;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.server.SessionIdManager;
-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 String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId";  
-    
-    protected Random _random;
-    protected boolean _weakRandom;
-    protected String _workerName;
-    protected long _reseed=100000L;
-    
-    /* ------------------------------------------------------------ */
-    public AbstractSessionIdManager()
-    {
-    }
-    
-    /* ------------------------------------------------------------ */
-    public AbstractSessionIdManager(Random random)
-    {
-        _random=random;
-    }
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return the reseed probability
-     */
-    public long getReseed()
-    {
-        return _reseed;
-    }
-
-    /* ------------------------------------------------------------ */
-    /** Set the reseed probability.
-     * @param reseed  If non zero then when a random long modulo the reseed value == 1, the {@link SecureRandom} will be reseeded.
-     */
-    public void setReseed(long reseed)
-    {
-        _reseed = reseed;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Get the workname. If set, the workername is dot appended to the session
-     * ID and can be used to assist session affinity in a load balancer.
-     * 
-     * @return String or null
-     */
-    public String getWorkerName()
-    {
-        return _workerName;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Set the workname. If set, the workername is dot appended to the session
-     * ID and can be used to assist session affinity in a load balancer.
-     * 
-     * @param workerName
-     */
-    public void setWorkerName(String workerName)
-    {
-        if (workerName.contains("."))
-            throw new IllegalArgumentException("Name cannot contain '.'");
-        _workerName=workerName;
-    }
-
-    /* ------------------------------------------------------------ */
-    public Random getRandom()
-    {
-        return _random;
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized void setRandom(Random random)
-    {
-        _random=random;
-        _weakRandom=false;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /** 
-     * Create a new session id if necessary.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#newSessionId(javax.servlet.http.HttpServletRequest, long)
-     */
-    public String newSessionId(HttpServletRequest request, long created)
-    {
-        synchronized (this)
-        {
-            if (request!=null)
-            {
-                // A requested session ID can only be used if it is in use already.
-                String requested_id=request.getRequestedSessionId();
-                if (requested_id!=null)
-                {
-                    String cluster_id=getClusterId(requested_id);
-                    if (idInUse(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))
-                    return new_id;
-            }
-            
-            // pick a new unique ID!
-            String id=null;
-            while (id==null||id.length()==0||idInUse(id))
-            {
-                long r0=_weakRandom
-                ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^(((long)request.hashCode())<<32))
-                :_random.nextLong();
-                if (r0<0)
-                    r0=-r0;
-
-		// random chance to reseed
-		if (_reseed>0 && (r0%_reseed)== 1L)
-		{
-		    LOG.debug("Reseeding {}",this);
-		    if (_random instanceof SecureRandom)
-		    {
-			SecureRandom secure = (SecureRandom)_random;
-			secure.setSeed(secure.generateSeed(8));
-		    }
-		    else
-		    {
-			_random.setSeed(_random.nextLong()^System.currentTimeMillis()^request.hashCode()^Runtime.getRuntime().freeMemory());
-		    }
-		}
-
-                long r1=_weakRandom
-                ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^(((long)request.hashCode())<<32))
-                :_random.nextLong();
-                if (r1<0)
-                    r1=-r1;
-                id=Long.toString(r0,36)+Long.toString(r1,36);
-                
-                //add in the id of the node to ensure unique id across cluster
-                //NOTE this is different to the node suffix which denotes which node the request was received on
-                if (_workerName!=null)
-                    id=_workerName + id;
-            }
-
-            request.setAttribute(__NEW_SESSION_ID,id);
-            return id;
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doStart() throws Exception
-    {
-       initRandom();
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doStop() throws Exception
-    {
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * Set up a random number generator for the sessionids.
-     * 
-     * By preference, use a SecureRandom but allow to be injected.
-     */
-    public void initRandom ()
-    {
-        if (_random==null)
-        {
-            try
-            {
-                _random=new SecureRandom();
-            }
-            catch (Exception e)
-            {
-                LOG.warn("Could not generate SecureRandom for session-id randomness",e);
-                _random=new Random();
-                _weakRandom=true;
-            }
-        }
-        else
-            _random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory()); 
-    }
-    
-    
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/AbstractSessionManager.java
--- a/src/org/eclipse/jetty/server/session/AbstractSessionManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1026 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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 static java.lang.Math.round;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.EventListener;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.SessionCookieConfig;
-import javax.servlet.SessionTrackingMode;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpSessionAttributeListener;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionContext;
-import javax.servlet.http.HttpSessionEvent;
-import javax.servlet.http.HttpSessionListener;
-
-import org.eclipse.jetty.http.HttpCookie;
-import org.eclipse.jetty.server.AbstractConnector;
-import org.eclipse.jetty.server.Request;
-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.component.AbstractLifeCycle;
-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. 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 specialised version of the Session inner class that provides an attribute
- * Map.
- * <p>
- */
-@SuppressWarnings("deprecation")
-public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager
-{
-    final static Logger __log = SessionHandler.LOG;
-
-    public Set<SessionTrackingMode> __defaultSessionTrackingModes =
-        Collections.unmodifiableSet(
-            new HashSet<SessionTrackingMode>(
-                    Arrays.asList(new SessionTrackingMode[]{SessionTrackingMode.COOKIE,SessionTrackingMode.URL})));
-        
-    public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated";
-    
-    /* ------------------------------------------------------------ */
-    public final static int __distantFuture=60*60*24*7*52*20;
-
-    static final HttpSessionContext __nullSessionContext=new HttpSessionContext()
-    {
-        public HttpSession getSession(String sessionId)
-        {
-            return null;
-        }
-        
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        public Enumeration getIds()
-        {
-            return Collections.enumeration(Collections.EMPTY_LIST);
-        }
-    };
-    
-    private boolean _usingCookies=true;
-
-    /* ------------------------------------------------------------ */
-    // Setting of max inactive interval for new sessions
-    // -1 means no timeout
-    protected int _dftMaxIdleSecs=-1;
-    protected SessionHandler _sessionHandler;
-    protected boolean _httpOnly=false;
-    protected SessionIdManager _sessionIdManager;
-    protected boolean _secureCookies=false;
-    protected boolean _secureRequestOnly=true;
-
-    protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>();
-    protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>();
-
-    protected ClassLoader _loader;
-    protected ContextHandler.Context _context;
-    protected String _sessionCookie=__DefaultSessionCookie;
-    protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName;
-    protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"=";
-    protected String _sessionDomain;
-    protected String _sessionPath;
-    protected int _maxCookieAge=-1;
-    protected int _refreshCookieAge;
-    protected boolean _nodeIdInSessionId;
-    protected boolean _checkingRemoteSessionIdEncoding;
-    protected String _sessionComment;
-
-    public Set<SessionTrackingMode> _sessionTrackingModes;
-
-    private boolean _usingURLs;
-    
-    protected final CounterStatistic _sessionsStats = new CounterStatistic();
-    protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
-    
-    
-    /* ------------------------------------------------------------ */
-    public static HttpSession renewSession (HttpServletRequest request, HttpSession httpSession, boolean authenticated)
-    {
-        Map<String,Object> attributes = new HashMap<String, Object>();
-
-        for (Enumeration<String> e=httpSession.getAttributeNames();e.hasMoreElements();)
-        {
-            String name=e.nextElement();
-            attributes.put(name,httpSession.getAttribute(name));
-            httpSession.removeAttribute(name);
-        }
-
-        httpSession.invalidate();       
-        httpSession = request.getSession(true);
-        if (authenticated)
-            httpSession.setAttribute(SESSION_KNOWN_ONLY_TO_AUTHENTICATED, Boolean.TRUE);
-        for (Map.Entry<String, Object> entry: attributes.entrySet())
-            httpSession.setAttribute(entry.getKey(),entry.getValue());
-        return httpSession;
-    }
-    
-    /* ------------------------------------------------------------ */
-    public AbstractSessionManager()
-    {
-        setSessionTrackingModes(__defaultSessionTrackingModes);
-    }
-
-    /* ------------------------------------------------------------ */
-    public ContextHandler.Context getContext()
-    {
-        return _context;
-    }
-
-    /* ------------------------------------------------------------ */
-    public ContextHandler getContextHandler()
-    {
-        return _context.getContextHandler();
-    }
-    
-    public String getSessionPath()
-    {
-        return _sessionPath;
-    }
-
-    public int getMaxCookieAge()
-    {
-        return _maxCookieAge;
-    }
-
-    /* ------------------------------------------------------------ */
-    public HttpCookie access(HttpSession session,boolean secure)
-    {
-        long now=System.currentTimeMillis();
-
-        AbstractSession s = ((SessionIf)session).getSession();
-
-       if (s.access(now))
-       {
-            // Do we need to refresh the cookie?
-            if (isUsingCookies() &&
-                (s.isIdChanged() ||
-                (getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge()))
-                )
-               )
-            {
-                HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure);
-                s.cookieSet();
-                s.setIdChanged(false);
-                return cookie;
-            }
-        }
-        return null;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void addEventListener(EventListener listener)
-    {
-        if (listener instanceof HttpSessionAttributeListener)
-            _sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
-        if (listener instanceof HttpSessionListener)
-            _sessionListeners.add((HttpSessionListener)listener);
-    }
-
-    /* ------------------------------------------------------------ */
-    public void clearEventListeners()
-    {
-        _sessionAttributeListeners.clear();
-        _sessionListeners.clear();
-    }
-
-    /* ------------------------------------------------------------ */
-    public void complete(HttpSession session)
-    {
-        AbstractSession s = ((SessionIf)session).getSession();
-        s.complete();
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void doStart() throws Exception
-    {
-        _context=ContextHandler.getCurrentContext();
-        _loader=Thread.currentThread().getContextClassLoader();
-
-        if (_sessionIdManager==null)
-        {
-            final Server server=getSessionHandler().getServer();
-            synchronized (server)
-            {
-                _sessionIdManager=server.getSessionIdManager();
-                if (_sessionIdManager==null)
-                {
-                    _sessionIdManager=new HashSessionIdManager();
-                    server.setSessionIdManager(_sessionIdManager);
-                }
-            }
-        }
-        if (!_sessionIdManager.isStarted())
-            _sessionIdManager.start();
-
-        // Look for a session cookie name
-        if (_context!=null)
-        {
-            String tmp=_context.getInitParameter(SessionManager.__SessionCookieProperty);
-            if (tmp!=null)
-                _sessionCookie=tmp;
-
-            tmp=_context.getInitParameter(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);
-                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);
-
-            // set up the sessionPath if it isn't already
-            if (_sessionPath==null)
-                _sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty);
-            
-            tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding);
-            if (tmp!=null)
-                _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
-        }
-
-        super.doStart();
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void doStop() throws Exception
-    {
-        super.doStop();
-
-        invalidateSessions();
-
-        _loader=null;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the httpOnly.
-     */
-    public boolean getHttpOnly()
-    {
-        return _httpOnly;
-    }
-
-    /* ------------------------------------------------------------ */
-    public HttpSession getHttpSession(String nodeId)
-    {
-        String cluster_id = getSessionIdManager().getClusterId(nodeId);
-
-        AbstractSession session = getSession(cluster_id);
-        if (session!=null && !session.getNodeId().equals(nodeId))
-            session.setIdChanged(true);
-        return session;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the metaManager used for cross context session management
-     * @deprecated Use {@link #getSessionIdManager()}
-     */
-    public SessionIdManager getIdManager()
-    {
-        return getSessionIdManager();
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the SessionIdManager used for cross context session management
-     */
-    public SessionIdManager getSessionIdManager()
-    {
-        return _sessionIdManager;
-    }
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return seconds
-     */
-    @Override
-    public int getMaxInactiveInterval()
-    {
-        return _dftMaxIdleSecs;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @see #getSessionsMax()
-     */
-    @Deprecated
-    public int getMaxSessions()
-    {
-        return getSessionsMax();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return maximum number of sessions
-     */
-    public int getSessionsMax()
-    {
-        return (int)_sessionsStats.getMax();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return total number of sessions
-     */
-    public int getSessionsTotal()
-    {
-        return (int)_sessionsStats.getTotal();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @deprecated use {@link #getSessionIdManager()}
-     */
-    @Deprecated
-    public SessionIdManager getMetaManager()
-    {
-        return getSessionIdManager();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @deprecated always returns 0. no replacement available.
-     */
-    @Deprecated
-    public int getMinSessions()
-    {
-        return 0;
-    }
-
-    /* ------------------------------------------------------------ */
-    public int getRefreshCookieAge()
-    {
-        return _refreshCookieAge;
-    }
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return same as SessionCookieConfig.getSecure(). If true, session
-     * cookies are ALWAYS marked as secure. If false, a session cookie is
-     * ONLY marked as secure if _secureRequestOnly == true and it is a HTTPS request.
-     */
-    public boolean getSecureCookies()
-    {
-        return _secureCookies;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true if session cookie is to be marked as secure only on HTTPS requests
-     */
-    public boolean isSecureRequestOnly()
-    {
-        return _secureRequestOnly;
-    }
-    
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @return if true, session cookie will be marked as secure only iff 
-     * HTTPS request. Can be overridden by setting SessionCookieConfig.setSecure(true),
-     * in which case the session cookie will be marked as secure on both HTTPS and HTTP.
-     */
-    public void setSecureRequestOnly(boolean secureRequestOnly)
-    {
-        _secureRequestOnly = secureRequestOnly;
-    }
-
-    
-    
-    /* ------------------------------------------------------------ */
-    public String getSessionCookie()
-    {
-        return _sessionCookie;
-    }
-
-    /* ------------------------------------------------------------ */
-    /** 
-     * A sessioncookie is marked as secure IFF any of the following conditions are true:
-     * <ol>
-     * <li>SessionCookieConfig.setSecure == true</li>
-     * <li>SessionCookieConfig.setSecure == false && _secureRequestOnly==true && request is HTTPS</li>
-     * </ol>
-     * According to SessionCookieConfig javadoc, case 1 can be used when:
-     * "... even though the request that initiated the session came over HTTP, 
-     * is to support a topology where the web container is front-ended by an 
-     * SSL offloading load balancer. In this case, the traffic between the client 
-     * and the load balancer will be over HTTPS, whereas the traffic between the 
-     * load balancer and the web container will be over HTTP."
-     * 
-     * For case 2, you can use _secureRequestOnly to determine if you want the
-     * Servlet Spec 3.0  default behaviour when SessionCookieConfig.setSecure==false, 
-     * which is:
-     * "they shall be marked as secure only if the request that initiated the 
-     * corresponding session was also secure"
-     * 
-     * The default for _secureRequestOnly is true, which gives the above behaviour. If
-     * you set it to false, then a session cookie is NEVER marked as secure, even if
-     * the initiating request was secure.
-     * 
-     * @see org.eclipse.jetty.server.SessionManager#getSessionCookie(javax.servlet.http.HttpSession, java.lang.String, boolean)
-     */
-    public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
-    {
-        if (isUsingCookies())
-        {
-            String sessionPath = (_sessionPath==null) ? contextPath : _sessionPath;
-            sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
-            String id = getNodeId(session);
-            HttpCookie cookie = null;
-            if (_sessionComment == null)
-            {
-                cookie = new HttpCookie(
-                                        _sessionCookie,
-                                        id,
-                                        _sessionDomain,
-                                        sessionPath,
-                                        _cookieConfig.getMaxAge(),
-                                        _cookieConfig.isHttpOnly(),
-                                        _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure));                  
-            }
-            else
-            {
-                cookie = new HttpCookie(
-                                        _sessionCookie,
-                                        id,
-                                        _sessionDomain,
-                                        sessionPath,
-                                        _cookieConfig.getMaxAge(),
-                                        _cookieConfig.isHttpOnly(),
-                                        _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure),
-                                        _sessionComment,
-                                        1);    
-            }
-
-            return cookie;
-        }
-        return null;
-    }
-
-    public String getSessionDomain()
-    {
-        return _sessionDomain;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the sessionHandler.
-     */
-    public SessionHandler getSessionHandler()
-    {
-        return _sessionHandler;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @deprecated  Need to review if it is needed.
-     */
-    @SuppressWarnings("rawtypes")
-    public Map getSessionMap()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-   
-
-    /* ------------------------------------------------------------ */
-    public int getSessions()
-    {
-        return (int)_sessionsStats.getCurrent();
-    }
-
-    /* ------------------------------------------------------------ */
-    public String getSessionIdPathParameterName()
-    {
-        return _sessionIdPathParameterName;
-    }
-
-    /* ------------------------------------------------------------ */
-    public String getSessionIdPathParameterNamePrefix()
-    {
-        return _sessionIdPathParameterNamePrefix;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the usingCookies.
-     */
-    public boolean isUsingCookies()
-    {
-        return _usingCookies;
-    }
-
-    /* ------------------------------------------------------------ */
-    public boolean isValid(HttpSession session)
-    {
-        AbstractSession s = ((SessionIf)session).getSession();
-        return s.isValid();
-    }
-
-    /* ------------------------------------------------------------ */
-    public String getClusterId(HttpSession session)
-    {
-        AbstractSession s = ((SessionIf)session).getSession();
-        return s.getClusterId();
-    }
-
-    /* ------------------------------------------------------------ */
-    public String getNodeId(HttpSession session)
-    {
-        AbstractSession s = ((SessionIf)session).getSession();
-        return s.getNodeId();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Create a new HttpSession for a request
-     */
-    public HttpSession newHttpSession(HttpServletRequest request)
-    {
-        AbstractSession session=newSession(request);
-        session.setMaxInactiveInterval(_dftMaxIdleSecs);
-        addSession(session,true);
-        return session;
-    }
-
-    /* ------------------------------------------------------------ */
-    public void removeEventListener(EventListener listener)
-    {
-        if (listener instanceof HttpSessionAttributeListener)
-            _sessionAttributeListeners.remove(listener);
-        if (listener instanceof HttpSessionListener)
-            _sessionListeners.remove(listener);
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @see #statsReset()
-     */
-    @Deprecated
-    public void resetStats()
-    {
-        statsReset();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Reset statistics values
-     */
-    public void statsReset()
-    {
-        _sessionsStats.reset(getSessions());
-        _sessionTimeStats.reset();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param httpOnly
-     *            The httpOnly to set.
-     */
-    public void setHttpOnly(boolean httpOnly)
-    {
-        _httpOnly=httpOnly;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param metaManager The metaManager used for cross context session management.
-     * @deprecated use {@link #setSessionIdManager(SessionIdManager)}
-     */
-    public void setIdManager(SessionIdManager metaManager)
-    {
-        setSessionIdManager(metaManager);
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @param metaManager The metaManager used for cross context session management.
-     */
-    public void setSessionIdManager(SessionIdManager metaManager)
-    {
-        _sessionIdManager=metaManager;
-    }
-
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param seconds
-     */
-    public void setMaxInactiveInterval(int seconds)
-    {
-        _dftMaxIdleSecs=seconds;
-    }
-
-
-    /* ------------------------------------------------------------ */
-    public void setRefreshCookieAge(int ageInSeconds)
-    {
-        _refreshCookieAge=ageInSeconds;
-    }
-
-
-
-    public void setSessionCookie(String cookieName)
-    {
-        _sessionCookie=cookieName;
-    }
-
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param sessionHandler
-     *            The sessionHandler to set.
-     */
-    public void setSessionHandler(SessionHandler sessionHandler)
-    {
-        _sessionHandler=sessionHandler;
-    }
-
- 
-    /* ------------------------------------------------------------ */
-    public void setSessionIdPathParameterName(String param)
-    {
-        _sessionIdPathParameterName =(param==null||"none".equals(param))?null:param;
-        _sessionIdPathParameterNamePrefix =(param==null||"none".equals(param))?null:(";"+ _sessionIdPathParameterName +"=");
-    }
-    /* ------------------------------------------------------------ */
-    /**
-     * @param usingCookies
-     *            The usingCookies to set.
-     */
-    public void setUsingCookies(boolean usingCookies)
-    {
-        _usingCookies=usingCookies;
-    }
-
-
-    protected abstract void addSession(AbstractSession session);
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Add the session Registers the session with this manager and registers the
-     * session ID with the sessionIDManager;
-     */
-    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.
-     * @return A Session or null if none exists.
-     */
-    public abstract AbstractSession getSession(String idInCluster);
-
-    protected abstract void invalidateSessions() throws Exception;
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Create a new session instance
-     * @param request
-     * @return the new session
-     */
-    protected abstract AbstractSession newSession(HttpServletRequest request);
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return true if the cluster node id (worker id) is returned as part of the session id by {@link HttpSession#getId()}. Default is false.
-     */
-    public boolean isNodeIdInSessionId()
-    {
-        return _nodeIdInSessionId;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param nodeIdInSessionId true if the cluster node id (worker id) will be returned as part of the session id by {@link HttpSession#getId()}. Default is false.
-     */
-    public void setNodeIdInSessionId(boolean nodeIdInSessionId)
-    {
-        _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 invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
-     * {@link SessionIdManager#invalidateAll(String)} should be called.
-     */
-    public void removeSession(AbstractSession session, boolean invalidate)
-    {
-        // Remove session from context and global maps
-        boolean removed = removeSession(session.getClusterId());
-        
-        if (removed)
-        {
-            _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)
-            {
-                HttpSessionEvent event=new HttpSessionEvent(session);
-                for (HttpSessionListener listener : _sessionListeners)
-                    listener.sessionDestroyed(event);
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    protected abstract boolean removeSession(String idInCluster);
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @return maximum amount of time session remained valid
-     */
-    public long getSessionTimeMax()
-    {
-        return _sessionTimeStats.getMax();
-    }
-
-    /* ------------------------------------------------------------ */
-    public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
-    {
-        return __defaultSessionTrackingModes;
-    }
-
-    /* ------------------------------------------------------------ */
-    public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
-    {
-        return Collections.unmodifiableSet(_sessionTrackingModes);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
-    {
-        _sessionTrackingModes=new HashSet<SessionTrackingMode>(sessionTrackingModes);
-        _usingCookies=_sessionTrackingModes.contains(SessionTrackingMode.COOKIE);
-        _usingURLs=_sessionTrackingModes.contains(SessionTrackingMode.URL);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public boolean isUsingURLs()
-    {
-        return _usingURLs;
-    }
-
-
-    /* ------------------------------------------------------------ */
-    public SessionCookieConfig getSessionCookieConfig()
-    {
-        return _cookieConfig;
-    } 
-
-    /* ------------------------------------------------------------ */
-    private SessionCookieConfig _cookieConfig =
-        new SessionCookieConfig()
-        {
-            @Override
-            public String getComment()
-            {
-                return _sessionComment;
-            }
-
-            @Override
-            public String getDomain()
-            {
-                return _sessionDomain;
-            }
-
-            @Override
-            public int getMaxAge()
-            {
-                return _maxCookieAge;
-            }
-
-            @Override
-            public String getName()
-            {
-                return _sessionCookie;
-            }
-
-            @Override
-            public String getPath()
-            {
-                return _sessionPath;
-            }
-
-            @Override
-            public boolean isHttpOnly()
-            {
-                return _httpOnly;
-            }
-
-            @Override
-            public boolean isSecure()
-            {
-                return _secureCookies;
-            }
-
-            @Override
-            public void setComment(String comment)
-            {
-                _sessionComment = comment; 
-            }
-
-            @Override
-            public void setDomain(String domain)
-            {
-                _sessionDomain=domain;
-            }
-
-            @Override
-            public void setHttpOnly(boolean httpOnly)
-            {
-                _httpOnly=httpOnly;
-            }
-
-            @Override
-            public void setMaxAge(int maxAge)
-            {
-                _maxCookieAge=maxAge;
-            }
-
-            @Override
-            public void setName(String name)
-            {
-                _sessionCookie=name;
-            }
-
-            @Override
-            public void setPath(String path)
-            {
-                _sessionPath=path;
-            }
-
-            @Override
-            public void setSecure(boolean secure)
-            {
-                _secureCookies=secure;
-            }
-        
-        };
-
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return total amount of time all sessions remained valid
-     */
-    public long getSessionTimeTotal()
-    {
-        return _sessionTimeStats.getTotal();
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @return mean amount of time session remained valid
-     */
-    public double getSessionTimeMean()
-    {
-        return _sessionTimeStats.getMean();
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @return standard deviation of amount of time session remained valid
-     */
-    public double getSessionTimeStdDev()
-    {
-        return _sessionTimeStats.getStdDev();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding()
-     */
-    public boolean isCheckingRemoteSessionIdEncoding()
-    {
-        return _checkingRemoteSessionIdEncoding;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean)
-     */
-    public void setCheckingRemoteSessionIdEncoding(boolean remote)
-    {
-        _checkingRemoteSessionIdEncoding=remote;
-    }
-    
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    /**
-     * Interface that any session wrapper should implement so that
-     * SessionManager may access the Jetty session implementation.
-     *
-     */
-    public interface SessionIf extends HttpSession
-    {
-        public AbstractSession getSession();
-    }
-
-    public void doSessionAttributeListeners(AbstractSession session, String name, Object old, Object value)
-    {
-        if (!_sessionAttributeListeners.isEmpty())
-        {
-            HttpSessionBindingEvent event=new HttpSessionBindingEvent(session,name,old==null?value:old);
-
-            for (HttpSessionAttributeListener l : _sessionAttributeListeners)
-            {
-                if (old==null)
-                    l.attributeAdded(event);
-                else if (value==null)
-                    l.attributeRemoved(event);
-                else
-                    l.attributeReplaced(event);
-            }
-        }
-    }
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/HashSessionIdManager.java
--- a/src/org/eclipse/jetty/server/session/HashSessionIdManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.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.SessionIdManager;
-
-/* ------------------------------------------------------------ */
-/**
- * HashSessionIdManager. An in-memory implementation of the session ID manager.
- */
-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
-     */
-    public Collection<String> getSessions()
-    {
-        return Collections.unmodifiableCollection(_sessions.keySet());
-    }
-    
-    /* ------------------------------------------------------------ */
-    /**
-     * @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;
-    }
-    /* ------------------------------------------------------------ */
-    /** Get the session ID with any worker ID.
-     * 
-     * @param clusterId
-     * @param request
-     * @return sessionId plus any worker ID.
-     */
-    public String getNodeId(String clusterId,HttpServletRequest request) 
-    {
-        // used in Ajp13Parser
-        String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute");
-        if (worker!=null) 
-            return clusterId+'.'+worker; 
-        
-        if (_workerName!=null) 
-            return clusterId+'.'+_workerName;
-       
-        return clusterId;
-    }
-
-    /* ------------------------------------------------------------ */
-    /** Get the session ID without any worker ID.
-     * 
-     * @param nodeId the node id
-     * @return sessionId without any worker ID.
-     */
-    public String getClusterId(String nodeId) 
-    {
-        int dot=nodeId.lastIndexOf('.');
-        return (dot>0)?nodeId.substring(0,dot):nodeId;
-    }
-    
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doStart() throws Exception
-    {        
-        super.doStart();
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    protected void doStop() throws Exception
-    {
-        _sessions.clear(); 
-        super.doStop();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see SessionIdManager#idInUse(String)
-     */
-    public boolean idInUse(String id)
-    {
-        synchronized (this)
-        {
-            return _sessions.containsKey(id);
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see SessionIdManager#addSession(HttpSession)
-     */
-    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)
-     */
-    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)
-     */
-    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();
-        }
-    }
-
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/HashSessionManager.java
--- a/src/org/eclipse/jetty/server/session/HashSessionManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,640 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.IO;
-import org.eclipse.jetty.util.log.Logger;
-
-
-/* ------------------------------------------------------------ */
-/** 
- * 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.
- *
- */
-public class HashSessionManager extends AbstractSessionManager
-{
-    final static Logger __log = SessionHandler.LOG;
-
-    protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>();
-    private static int __id;
-    private Timer _timer;
-    private boolean _timerStop=false;
-    private TimerTask _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 TimerTask _saveTask;
-    File _storeDir;
-    private boolean _lazyLoad=false;
-    private volatile boolean _sessionsLoaded=false;
-    private boolean _deleteUnrestorableSessions=false;
-    
-
-
-
-    /* ------------------------------------------------------------ */
-    public HashSessionManager()
-    {
-        super();
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.servlet.AbstractSessionManager#doStart()
-     */
-    @Override
-    public void doStart() throws Exception
-    {
-        super.doStart();
-
-        _timerStop=false;
-        ServletContext context = ContextHandler.getCurrentContext();
-        if (context!=null)
-            _timer=(Timer)context.getAttribute("org.eclipse.jetty.server.session.timer");
-        if (_timer==null)
-        {
-            _timerStop=true;
-            _timer=new Timer("HashSessionScavenger-"+__id++, true);
-        }
-
-        setScavengePeriod(getScavengePeriod());
-
-        if (_storeDir!=null)
-        {
-            if (!_storeDir.exists())
-                _storeDir.mkdirs();
-
-            if (!_lazyLoad)
-                restoreSessions();
-        }
-
-        setSavePeriod(getSavePeriod());
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @see org.eclipse.jetty.servlet.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;
-            if (_timer!=null && _timerStop)
-                _timer.cancel();
-            _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();
-                if (_savePeriodMs > 0 && _storeDir!=null) //only save if we have a directory configured
-                {
-                    _saveTask = new TimerTask()
-                    {
-                        @Override
-                        public void run()
-                        {
-                            try
-                            {
-                                saveSessions(true);
-                            }
-                            catch (Exception e)
-                            {
-                                __log.warn(e);
-                            }
-                        }
-                    };
-                    _timer.schedule(_saveTask,_savePeriodMs,_savePeriodMs);
-                }
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @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;
-    
-        if (_timer!=null && (period!=old_period || _task==null))
-        {
-            synchronized (this)
-            {
-                if (_task!=null)
-                    _task.cancel();
-                _task = new TimerTask()
-                {
-                    @Override
-                    public void run()
-                    {
-                        scavenge();
-                    }
-                };
-                _timer.schedule(_task,_scavengePeriodMs,_scavengePeriodMs);
-            }
-        }
-    }
-
-    /* -------------------------------------------------------------- */
-    /**
-     * 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();
-          
-            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 invalidateSessions() 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 - it is not invalidated.
-                for (HashedSession session : sessions)
-                {
-                    session.save(false);
-                    removeSession(session,false);
-                }
-            }
-            else
-            {
-                for (HashedSession session : sessions)
-                    session.invalidate();
-            }
-
-            // check that no new sessions were created while we were iterating
-            sessions=new ArrayList<HashedSession>(_sessions.values());
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    @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);
-
-        FileInputStream in = null;
-        Exception error = null;
-        try
-        {
-            if (file.exists())
-            {
-                in = new FileInputStream(file);
-                HashedSession session = restoreSession(in, null);
-                addSession(session, false);
-                session.didActivate();
-                return session;
-            }
-        }
-        catch (Exception e)
-        {
-           error = e;
-        }
-        finally
-        {
-            if (in != null) IO.close(in);
-            
-            if (error != null)
-            {
-                if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) )
-                {
-                    file.delete();
-                    __log.warn("Deleting file for unrestorable session "+idInCuster, error);
-                }
-                else
-                {
-                    __log.warn("Problem restoring session "+idInCuster, error);
-                }
-            }
-            else
-               file.delete(); //delete successfully restored file
-                
-        }
-        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(true);
-    }
-
-    /* ------------------------------------------------------------ */
-    public HashedSession restoreSession (InputStream is, HashedSession session) throws Exception
-    {
-        /*
-         * Take care of this class's fields first by calling
-         * defaultReadObject
-         */
-        DataInputStream in = new DataInputStream(is);
-        try
-        {
-            String clusterId = in.readUTF();
-            in.readUTF(); // nodeId
-            long created = in.readLong();
-            long accessed = in.readLong();
-            int requests = in.readInt();
-
-            if (session == null)
-                session = (HashedSession)newSession(created, accessed, clusterId);
-            session.setRequests(requests);
-            int size = in.readInt();
-            if (size>0)
-            {
-                ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(in);
-                try
-                {
-                    for (int i=0; i<size;i++)
-                    {
-                        String key = ois.readUTF();
-                        Object value = ois.readObject();
-                        session.setAttribute(key,value);
-                    }
-                }
-                finally
-                {
-                    IO.close(ois);
-                }
-            }
-            return session;
-        }
-        finally
-        {
-            IO.close(in);
-        }
-    }
-
-
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    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 -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/HashedSession.java
--- a/src/org/eclipse/jetty/server/session/HashedSession.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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 AbstractSession
-{
-    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;
-
-    /* ------------------------------------------------------------- */
-    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 (_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 from the disk
-        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);
-
-            File file = null;
-            FileOutputStream fos = null;
-            
-            try
-            {
-                file = new File(_hashSessionManager._storeDir, super.getId());
-
-                if (file.exists())
-                    file.delete();
-                file.createNewFile();
-                fos = new FileOutputStream(file);
-                willPassivate();
-                save(fos);
-                IO.close(fos);
-                if (reactivate)
-                    didActivate();
-                else
-                    clearAttributes();
-            }
-            catch (Exception e)
-            {
-                saveFailed(); // We won't try again for this session
-                if (fos != null) IO.close(fos);
-                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.writeLong(_maxIdleMs);
-        //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));
-        }
-        oos.close();
-    }
-
-    /* ------------------------------------------------------------ */
-    public synchronized void deIdle()
-    {
-        if (isIdled())
-        {
-            // 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)
-            {
-                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.  
-     */
-    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;
-    }
-
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/JDBCSessionIdManager.java
--- a/src/org/eclipse/jetty/server/session/JDBCSessionIdManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1040 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Random;
-import java.util.Timer;
-import java.util.TimerTask;
-
-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.Logger;
-
-
-
-/**
- * JDBCSessionIdManager
- *
- * SessionIdManager implementation that uses a database to store in-use session ids, 
- * to support distributed sessions.
- * 
- */
-public class JDBCSessionIdManager extends AbstractSessionIdManager
-{    
-    final static Logger LOG = SessionHandler.LOG;
-    
-    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 String _sessionIdTable = "JettySessionIds";
-    protected String _sessionTable = "JettySessions";
-    protected String _sessionTableRowId = "rowId";
-    
-    protected Timer _timer; //scavenge timer
-    protected TimerTask _task; //scavenge task
-    protected long _lastScavengeTime;
-    protected long _scavengeIntervalMs = 1000L * 60 * 10; //10mins
-    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
-    
-    protected String _createSessionIdTable;
-    protected String _createSessionTable;
-                                            
-    protected String _selectBoundedExpiredSessions;
-    protected String _deleteOldExpiredSessions;
-
-    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;
-
-    private String _selectExpiredSessions;
-
-    
-    /**
-     * 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 class DatabaseAdaptor 
-    {
-        String _dbName;
-        boolean _isLower;
-        boolean _isUpper;
-       
-        
-        
-        public DatabaseAdaptor (DatabaseMetaData dbMeta)
-        throws SQLException
-        {
-            _dbName = dbMeta.getDatabaseProductName().toLowerCase(Locale.ENGLISH); 
-            LOG.debug ("Using database {}",_dbName);
-            _isLower = dbMeta.storesLowerCaseIdentifiers();
-            _isUpper = dbMeta.storesUpperCaseIdentifiers();            
-        }
-        
-        /**
-         * Convert a camel case identifier into either upper or lower
-         * depending on the way the db stores identifiers.
-         * 
-         * @param identifier
-         * @return the converted identifier
-         */
-        public String convertIdentifier (String identifier)
-        {
-            if (_isLower)
-                return identifier.toLowerCase(Locale.ENGLISH);
-            if (_isUpper)
-                return identifier.toUpperCase(Locale.ENGLISH);
-            
-            return identifier;
-        }
-        
-        public String getDBName ()
-        {
-            return _dbName;
-        }
-        
-        public String getBlobType ()
-        {
-            if (_blobType != null)
-                return _blobType;
-            
-            if (_dbName.startsWith("postgres"))
-                return "bytea";
-            
-            return "blob";
-        }
-        
-        public String getLongType ()
-        {
-            if (_longType != null)
-                return _longType;
-            
-            if (_dbName.startsWith("oracle"))
-                return "number(20)";
-            
-            return "bigint";
-        }
-        
-        public InputStream getBlobInputStream (ResultSet result, String columnName)
-        throws SQLException
-        {
-            if (_dbName.startsWith("postgres"))
-            {
-                byte[] bytes = result.getBytes(columnName);
-                return new ByteArrayInputStream(bytes);
-            }
-            
-            Blob blob = result.getBlob(columnName);
-            return blob.getBinaryStream();
-        }
-        
-        /**
-         * rowId is a reserved word for Oracle, so change the name of this column
-         * @return
-         */
-        public String getRowIdColumnName ()
-        {
-            if (_dbName != null && _dbName.startsWith("oracle"))
-                return "srowId";
-            
-            return "rowId";
-        }
-        
-        
-        public boolean isEmptyStringNull ()
-        {
-            return (_dbName.startsWith("oracle"));
-        }
-        
-        public PreparedStatement getLoadStatement (Connection connection, String rowId, String contextPath, String virtualHosts) 
-        throws SQLException
-        {
-            if (contextPath == null || "".equals(contextPath))
-            {
-                if (isEmptyStringNull())
-                {
-                    PreparedStatement statement = connection.prepareStatement("select * from "+_sessionTable+
-                    " where sessionId = ? and contextPath is null and virtualHost = ?");
-                    statement.setString(1, rowId);
-                    statement.setString(2, virtualHosts);
-
-                    return statement;
-                }
-            }
-           
-
-
-            PreparedStatement statement = connection.prepareStatement("select * from "+_sessionTable+
-            " where sessionId = ? and contextPath = ? and virtualHost = ?");
-            statement.setString(1, rowId);
-            statement.setString(2, contextPath);
-            statement.setString(3, virtualHosts);
-
-            return statement;
-        }
-    }
-    
-    
-    
-    public JDBCSessionIdManager(Server server)
-    {
-        super();
-        _server=server;
-    }
-    
-    public JDBCSessionIdManager(Server server, Random random)
-    {
-       super(random);
-       _server=server;
-    }
-
-    /**
-     * Configure jdbc connection information via a jdbc Driver
-     * 
-     * @param driverClassName
-     * @param connectionUrl
-     */
-    public void setDriverInfo (String driverClassName, String connectionUrl)
-    {
-        _driverClassName=driverClassName;
-        _connectionUrl=connectionUrl;
-    }
-    
-    /**
-     * Configure jdbc connection information via a jdbc Driver
-     * 
-     * @param driverClass
-     * @param connectionUrl
-     */
-    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;
-    }
-   
-    public void setBlobType (String name)
-    {
-        _blobType = name;
-    }
-    
-    public String getBlobType ()
-    {
-        return _blobType;
-    }
-    
-    
-    
-    public String getLongType()
-    {
-        return _longType;
-    }
-
-    public void setLongType(String longType)
-    {
-        this._longType = longType;
-    }
-
-    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");
-        if (_timer!=null && (period!=old_period || _task==null))
-        {
-            synchronized (this)
-            {
-                if (_task!=null)
-                    _task.cancel();
-                _task = new TimerTask()
-                {
-                    @Override
-                    public void run()
-                    {
-                        scavenge();
-                    }   
-                };
-                _timer.schedule(_task,_scavengeIntervalMs,_scavengeIntervalMs);
-            }
-        }  
-    }
-    
-    public long getScavengeInterval ()
-    {
-        return _scavengeIntervalMs/1000;
-    }
-    
-    
-    public void addSession(HttpSession 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 removeSession(HttpSession session)
-    {
-        if (session == null)
-            return;
-        
-        removeSession(((JDBCSessionManager.Session)session).getClusterId());
-    }
-    
-    
-    
-    public void removeSession (String id)
-    {
-
-        if (id == null)
-            return;
-        
-        synchronized (_sessionIds)
-        {  
-            if (LOG.isDebugEnabled())
-                LOG.debug("Removing session id="+id);
-            try
-            {               
-                _sessionIds.remove(id);
-                delete(id);
-            }
-            catch (Exception e)
-            {
-                LOG.warn("Problem removing session id="+id, e);
-            }
-        }
-        
-    }
-    
-
-    /** 
-     * Get the session id without any node identifier suffix.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#getClusterId(java.lang.String)
-     */
-    public String getClusterId(String nodeId)
-    {
-        int dot=nodeId.lastIndexOf('.');
-        return (dot>0)?nodeId.substring(0,dot):nodeId;
-    }
-    
-
-    /** 
-     * Get the session id, including this node's id as a suffix.
-     * 
-     * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest)
-     */
-    public String getNodeId(String clusterId, HttpServletRequest request)
-    {
-        if (_workerName!=null)
-            return clusterId+'.'+_workerName;
-
-        return clusterId;
-    }
-
-
-    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)
-     */
-    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 = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-                if (sessionHandler != null) 
-                {
-                    SessionManager manager = sessionHandler.getSessionManager();
-
-                    if (manager != null && manager instanceof JDBCSessionManager)
-                    {
-                        ((JDBCSessionManager)manager).invalidateSession(id);
-                    }
-                }
-            }
-        }
-    }
-
-
-    /** 
-     * Start up the id manager.
-     * 
-     * Makes necessary database tables and starts a Session
-     * scavenger thread.
-     */
-    @Override
-    public void doStart()
-    throws Exception
-    {           
-        initializeDatabase();
-        prepareTables();   
-        cleanExpiredSessions();
-        super.doStart();
-        if (LOG.isDebugEnabled()) 
-            LOG.debug("Scavenging interval = "+getScavengeInterval()+" sec");
-        _timer=new Timer("JDBCSessionScavenger", true);
-        setScavengeInterval(getScavengeInterval());
-    }
-
-    /** 
-     * Stop the scavenger.
-     */
-    @Override
-    public void doStop () 
-    throws Exception
-    {
-        synchronized(this)
-        {
-            if (_task!=null)
-                _task.cancel();
-            if (_timer!=null)
-                _timer.cancel();
-            _timer=null;
-        }
-        _sessionIds.clear();
-        super.doStop();
-    }
-  
-    /**
-     * Get a connection from the driver or datasource.
-     * 
-     * @return the connection for the datasource
-     * @throws SQLException
-     */
-    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
-     */
-    private void prepareTables()
-    throws SQLException
-    {
-        _createSessionIdTable = "create table "+_sessionIdTable+" (id varchar(120), primary key(id))";
-        _selectBoundedExpiredSessions = "select * from "+_sessionTable+" where expiryTime >= ? and expiryTime <= ?";
-        _selectExpiredSessions = "select * from "+_sessionTable+" where expiryTime >0 and expiryTime <= ?";
-        _deleteOldExpiredSessions = "delete from "+_sessionTable+" where expiryTime >0 and expiryTime <= ?";
-
-        _insertId = "insert into "+_sessionIdTable+" (id)  values (?)";
-        _deleteId = "delete from "+_sessionIdTable+" where id = ?";
-        _queryId = "select * from "+_sessionIdTable+" where id = ?";
-
-        Connection connection = null;
-        try
-        {
-            //make the id table
-            connection = getConnection();
-            connection.setAutoCommit(true);
-            DatabaseMetaData metaData = connection.getMetaData();
-            _dbAdaptor = new DatabaseAdaptor(metaData);
-            _sessionTableRowId = _dbAdaptor.getRowIdColumnName();
-
-            //checking for table existence is case-sensitive, but table creation is not
-            String tableName = _dbAdaptor.convertIdentifier(_sessionIdTable);
-            ResultSet result = metaData.getTables(null, null, tableName, null);
-            if (!result.next())
-            {
-                //table does not exist, so create it
-                connection.createStatement().executeUpdate(_createSessionIdTable);
-            }
-            
-            //make the session table if necessary
-            tableName = _dbAdaptor.convertIdentifier(_sessionTable);   
-            result = metaData.getTables(null, null, tableName, null);
-            if (!result.next())
-            {
-                //table does not exist, so create it
-                String blobType = _dbAdaptor.getBlobType();
-                String longType = _dbAdaptor.getLongType();
-                _createSessionTable = "create table "+_sessionTable+" ("+_sessionTableRowId+" varchar(120), sessionId varchar(120), "+
-                                           " contextPath varchar(60), virtualHost varchar(60), lastNode varchar(60), accessTime "+longType+", "+
-                                           " lastAccessTime "+longType+", createTime "+longType+", cookieTime "+longType+", "+
-                                           " lastSavedTime "+longType+", expiryTime "+longType+", map "+blobType+", primary key("+_sessionTableRowId+"))";
-                connection.createStatement().executeUpdate(_createSessionTable);
-            }
-            
-            //make some indexes on the JettySessions table
-            String index1 = "idx_"+_sessionTable+"_expiry";
-            String index2 = "idx_"+_sessionTable+"_session";
-            
-            result = metaData.getIndexInfo(null, null, tableName, false, false);
-            boolean index1Exists = false;
-            boolean index2Exists = 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 && index2Exists))
-            {
-                Statement statement = connection.createStatement();
-                try
-                {
-                    if (!index1Exists)
-                        statement.executeUpdate("create index "+index1+" on "+_sessionTable+" (expiryTime)");
-                    if (!index2Exists)
-                        statement.executeUpdate("create index "+index2+" on "+_sessionTable+" (sessionId, contextPath)");
-                }
-                finally
-                {
-                    if (statement!=null)
-                    {
-                        try { statement.close(); }
-                        catch(Exception e) { LOG.warn(e); }
-                    }
-                }
-            }
-
-            //set up some strings representing the statements for session manipulation
-            _insertSession = "insert into "+_sessionTable+
-            " ("+_sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+
-            " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
-
-            _deleteSession = "delete from "+_sessionTable+
-            " where "+_sessionTableRowId+" = ?";
-            
-            _updateSession = "update "+_sessionTable+
-            " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, map = ? where "+_sessionTableRowId+" = ?";
-
-            _updateSessionNode = "update "+_sessionTable+
-            " set lastNode = ? where "+_sessionTableRowId+" = ?";
-
-            _updateSessionAccessTime = "update "+_sessionTable+
-            " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+_sessionTableRowId+" = ?";
-
-            
-        }
-        finally
-        {
-            if (connection != null)
-                connection.close();
-        }
-    }
-    
-    /**
-     * Insert a new used session id into the table.
-     * 
-     * @param id
-     * @throws SQLException
-     */
-    private void insert (String id)
-    throws SQLException 
-    {
-        Connection connection = null;
-        PreparedStatement statement = null;
-        PreparedStatement query = null;
-        try
-        {
-            connection = getConnection();
-            connection.setAutoCommit(true);            
-            query = connection.prepareStatement(_queryId);
-            query.setString(1, id);
-            ResultSet result = query.executeQuery();
-            //only insert the id if it isn't in the db already 
-            if (!result.next())
-            {
-                statement = connection.prepareStatement(_insertId);
-                statement.setString(1, id);
-                statement.executeUpdate();
-            }
-        }
-        finally
-        {
-            if (query!=null)
-            {
-                try { query.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection != null)
-                connection.close();
-        }
-    }
-    
-    /**
-     * Remove a session id from the table.
-     * 
-     * @param id
-     * @throws SQLException
-     */
-    private void delete (String id)
-    throws SQLException
-    {
-        Connection connection = null;
-        PreparedStatement statement = null;
-        try
-        {
-            connection = getConnection();
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_deleteId);
-            statement.setString(1, id);
-            statement.executeUpdate();
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection != null)
-                connection.close();
-        }
-    }
-    
-    
-    /**
-     * Check if a session id exists.
-     * 
-     * @param id
-     * @return
-     * @throws SQLException
-     */
-    private boolean exists (String id)
-    throws SQLException
-    {
-        Connection connection = null;
-        PreparedStatement statement = null;
-        try
-        {
-            connection = getConnection();
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_queryId);
-            statement.setString(1, id);
-            ResultSet result = statement.executeQuery();
-            return result.next();
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection != null)
-                connection.close();
-        }
-    }
-    
-    /**
-     * 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 ()
-    {
-        Connection connection = null;
-        PreparedStatement statement = null;
-        List<String> expiredSessionIds = new ArrayList<String>();
-        try
-        {            
-            if (LOG.isDebugEnabled()) 
-                LOG.debug("Scavenge sweep started at "+System.currentTimeMillis());
-            if (_lastScavengeTime > 0)
-            {
-                connection = getConnection();
-                connection.setAutoCommit(true);
-                //"select sessionId from JettySessions where expiryTime > (lastScavengeTime - scanInterval) and expiryTime < lastScavengeTime";
-                statement = connection.prepareStatement(_selectBoundedExpiredSessions);
-                long lowerBound = (_lastScavengeTime - _scavengeIntervalMs);
-                long upperBound = _lastScavengeTime;
-                if (LOG.isDebugEnabled()) 
-                    LOG.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound);
-                
-                statement.setLong(1, lowerBound);
-                statement.setLong(2, upperBound);
-                ResultSet result = statement.executeQuery();
-                while (result.next())
-                {
-                    String sessionId = result.getString("sessionId");
-                    expiredSessionIds.add(sessionId);
-                    if (LOG.isDebugEnabled()) LOG.debug (" Found expired sessionId="+sessionId); 
-                }
-
-                //tell the SessionManagers to expire any sessions with a matching sessionId in memory
-                Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
-                for (int i=0; contexts!=null && i<contexts.length; i++)
-                {
-
-                    SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
-                    if (sessionHandler != null) 
-                    { 
-                        SessionManager manager = sessionHandler.getSessionManager();
-                        if (manager != null && manager instanceof JDBCSessionManager)
-                        {
-                            ((JDBCSessionManager)manager).expire(expiredSessionIds);
-                        }
-                    }
-                }
-
-                //find all sessions that have expired at least a couple of scanIntervals ago and just delete them
-                upperBound = _lastScavengeTime - (2 * _scavengeIntervalMs);
-                if (upperBound > 0)
-                {
-                    if (LOG.isDebugEnabled()) LOG.debug("Deleting old expired sessions expired before "+upperBound);
-                    try
-                    {
-                        statement = connection.prepareStatement(_deleteOldExpiredSessions);
-                        statement.setLong(1, upperBound);
-                        int rows = statement.executeUpdate();
-                        if (LOG.isDebugEnabled()) LOG.debug("Deleted "+rows+" rows of old sessions expired before "+upperBound);
-                    }
-                    finally
-                    {
-                        if (statement!=null)
-                        {
-                            try { statement.close(); }
-                            catch(Exception e) { LOG.warn(e); }
-                        }
-                    }
-                }
-            }
-        }
-        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("Scavenge sweep ended at "+_lastScavengeTime);
-            if (connection != null)
-            {
-                try
-                {
-                connection.close();
-                }
-                catch (SQLException e)
-                {
-                    LOG.warn(e);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Get rid of sessions and sessionids from sessions that have already expired
-     * @throws Exception
-     */
-    private void cleanExpiredSessions ()
-    {
-        Connection connection = null;
-        PreparedStatement statement = null;
-        Statement sessionsTableStatement = null;
-        Statement sessionIdsTableStatement = null;
-        List<String> expiredSessionIds = new ArrayList<String>();
-        try
-        {     
-            connection = getConnection();
-            connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
-            connection.setAutoCommit(false);
-
-            statement = connection.prepareStatement(_selectExpiredSessions);
-            long now = System.currentTimeMillis();
-            if (LOG.isDebugEnabled()) LOG.debug ("Searching for sessions expired before {}", now);
-
-            statement.setLong(1, now);
-            ResultSet result = statement.executeQuery();
-            while (result.next())
-            {
-                String sessionId = result.getString("sessionId");
-                expiredSessionIds.add(sessionId);
-                if (LOG.isDebugEnabled()) LOG.debug ("Found expired sessionId={}", sessionId); 
-            }
-            
-            sessionsTableStatement = null;
-            sessionIdsTableStatement = null;
-
-            if (!expiredSessionIds.isEmpty())
-            {
-                sessionsTableStatement = connection.createStatement();
-                sessionsTableStatement.executeUpdate(createCleanExpiredSessionsSql("delete from "+_sessionTable+" where sessionId in ", expiredSessionIds));
-                sessionIdsTableStatement = connection.createStatement();
-                sessionIdsTableStatement.executeUpdate(createCleanExpiredSessionsSql("delete from "+_sessionIdTable+" where id in ", expiredSessionIds));
-            }
-            connection.commit();
-
-            synchronized (_sessionIds)
-            {
-                _sessionIds.removeAll(expiredSessionIds); //in case they were in our local cache of session ids
-            }
-        }
-        catch (Exception e)
-        {
-            if (connection != null)
-            {
-                try 
-                { 
-                    LOG.warn("Rolling back clean of expired sessions", e);
-                    connection.rollback();
-                }
-                catch (Exception x) { LOG.warn("Rollback of expired sessions failed", x);}
-            }
-        }
-        finally
-        {
-            if (sessionIdsTableStatement!=null)
-            {
-                try { sessionIdsTableStatement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (sessionsTableStatement!=null)
-            {
-                try { sessionsTableStatement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            try
-            {
-                if (connection != null)
-                    connection.close();
-            }
-            catch (SQLException e)
-            {
-                LOG.warn(e);
-            }
-        }
-    }
-    
-    
-    /**
-     * 
-     * @param sql
-     * @param connection
-     * @param expiredSessionIds
-     * @throws Exception
-     */
-    private String createCleanExpiredSessionsSql (String sql,Collection<String> expiredSessionIds)
-    throws Exception
-    {
-        StringBuffer buff = new StringBuffer();
-        buff.append(sql);
-        buff.append("(");
-        Iterator<String> itor = expiredSessionIds.iterator();
-        while (itor.hasNext())
-        {
-            buff.append("'"+(itor.next())+"'");
-            if (itor.hasNext())
-                buff.append(",");
-        }
-        buff.append(")");
-        
-        if (LOG.isDebugEnabled()) LOG.debug("Cleaning expired sessions with: {}", buff);
-        return buff.toString();
-    }
-    
-    private void initializeDatabase ()
-    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
-            throw new IllegalStateException("No database configured for sessions");
-    }
-    
-   
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/JDBCSessionManager.java
--- a/src/org/eclipse/jetty/server/session/JDBCSessionManager.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1174 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.servlet.SessionTrackingMode;
-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.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/**
- * JDBCSessionManager
- *
- * SessionManager that persists sessions to a database to enable clustering.
- *
- * Session data is persisted to the JettySessions table:
- *
- * rowId (unique in cluster: webapp name/path + virtualhost + sessionId)
- * contextPath (of the context owning the session)
- * sessionId (unique in a context)
- * lastNode (name of node last handled session)
- * accessTime (time in milliseconds session was accessed)
- * lastAccessTime (previous time in milliseconds session was accessed)
- * createTime (time in milliseconds session created)
- * cookieTime (time in milliseconds session cookie created)
- * lastSavedTime (last time in milliseconds session access times were saved)
- * expiryTime (time in milliseconds that the session is due to expire)
- * map (attribute map)
- *
- * 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
-{
-    private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
-
-    private ConcurrentHashMap<String, AbstractSession> _sessions;
-    protected JDBCSessionIdManager _jdbcSessionIdMgr = null;
-    protected long _saveIntervalSec = 60; //only persist changes to session access times every 60 secs
-
-   
-
-
-    /**
-     * Session
-     *
-     * Session instance.
-     */
-    public class Session extends AbstractSession
-    {
-        private static final long serialVersionUID = 5208464051134226143L;
-        
-        /**
-         * If dirty, session needs to be (re)persisted
-         */
-        private boolean _dirty=false;
-        
-        
-        /**
-         * Time in msec since the epoch that a session cookie was set for this session
-         */
-        private long _cookieSet;
-        
-        
-        /**
-         * Time in msec since the epoch that the session will expire
-         */
-        private long _expiryTime;
-        
-        
-        /**
-         * Time in msec since the epoch that the session was last persisted
-         */
-        private long _lastSaved;
-        
-        
-        /**
-         * Unique identifier of the last node to host the session
-         */
-        private String _lastNode;
-        
-        
-        /**
-         * Virtual host for context (used to help distinguish 2 sessions with same id on different contexts)
-         */
-        private String _virtualHost;
-        
-        
-        /**
-         * Unique row in db for session
-         */
-        private String _rowId;
-        
-        
-        /**
-         * Mangled context name (used to help distinguish 2 sessions with same id on different contexts)
-         */
-        private String _canonicalContext;
-        
-   
-        /**
-         * Session from a request.
-         *
-         * @param 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
-         * @param rowId
-         * @param created
-         * @param accessed
-         */
-        protected Session (String sessionId, String rowId, long created, long accessed)
-        {
-            super(JDBCSessionManager.this, created, accessed, sessionId);
-            _rowId = rowId;
-        }
-        
-        
-        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 void setCookieSet (long ms)
-        {
-            _cookieSet = ms;
-        }
-
-        public synchronized long getCookieSet ()
-        {
-            return _cookieSet;
-        }
-
-        public synchronized void setLastNode (String node)
-        {
-            _lastNode=node;
-        }
-
-        public synchronized String getLastNode ()
-        {
-            return _lastNode;
-        }
-
-        @Override
-        public void setAttribute (String name, Object value)
-        {
-            super.setAttribute(name, value);
-            _dirty=true;
-        }
-
-        @Override
-        public void removeAttribute (String name)
-        {
-            super.removeAttribute(name);
-            _dirty=true;
-        }
-
-        @Override
-        protected void cookieSet()
-        {
-            _cookieSet = getAccessed();
-        }
-
-        /**
-         * 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;
-            }
-        }
-        
-
-
-        /**
-         * 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
-                            willPassivate();                      
-                            updateSession(this);
-                            didActivate();
-                        }
-                        else if ((getAccessed() - _lastSaved) >= (getSaveInterval() * 1000L))
-                        {
-                            updateSessionAccessTime(this);
-                        }
-                    }
-                }
-                catch (Exception e)
-                {
-                    LOG.warn("Problem persisting changed session data id="+getId(), e);
-                }
-                finally
-                {
-                    _dirty=false;
-                }
-            }
-        }
-
-        @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="+_cookieSet+
-                            ",lastSaved="+_lastSaved+",expiry="+_expiryTime;
-        }
-    }
-
-
-
-
-    /**
-     * ClassLoadingObjectInputStream
-     *
-     * Used to persist the session attribute map
-     */
-    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);
-            }
-        }
-    }
-
-
-    /**
-     * 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
-     */
-    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
-     */
-    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;
-        Session memSession = (Session)_sessions.get(idInCluster);
-
-        synchronized (this)
-        {
-                //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, "+
-                                " 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)
-                    {
-                        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))
-                    {
-                        LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
-                        session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
-                    }
-                    else
-                    {
-                        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);
-                            
-                            //update in db: if unable to update, session will be scavenged later
-                            try
-                            {
-                                updateSessionNode(session);
-                                session.didActivate();
-                            }
-                            catch (Exception e)
-                            {
-                                LOG.warn("Unable to update freshly loaded session "+idInCluster, e);
-                                return null;
-                            }
-                        }
-                        else
-                        {
-                            LOG.debug("getSession ({}): Session has expired", 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;
-                       LOG.debug("getSession({}): Session not stale {}", idInCluster,session);
-                    }
-                }
-                else
-                {
-                    //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()
-    {
-        int size = 0;
-        synchronized (this)
-        {
-            size = _sessions.size();
-        }
-        return size;
-    }
-
-
-    /**
-     * 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;
-        
-        _sessions = new ConcurrentHashMap<String, AbstractSession>();
-
-        super.doStart();
-    }
-
-
-    /**
-     * Stop the session manager.
-     *
-     * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStop()
-     */
-    @Override
-    public void doStop() throws Exception
-    {
-        _sessions.clear();
-        _sessions = null;
-
-        super.doStop();
-    }
-
-    @Override
-    protected void invalidateSessions()
-    {
-        //Do nothing - we don't want to remove and
-        //invalidate all the sessions because this
-        //method is called from doStop(), and just
-        //because this context is stopping does not
-        //mean that we should remove the session from
-        //any other nodes
-    }
-
-
-    /**
-     * Invalidate a session.
-     *
-     * @param idInCluster
-     */
-    protected void invalidateSession (String idInCluster)
-    {
-        Session session = null;
-        synchronized (this)
-        {
-            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)
-    {
-        synchronized (this)
-        {
-            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;
-
-        synchronized (this)
-        {
-            _sessions.put(session.getClusterId(), session);
-        }
-
-        //TODO or delay the store until exit out of session? If we crash before we store it
-        //then session data will be lost.
-        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);
-    }
-
-    /* ------------------------------------------------------------ */
-    /** 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 void removeSession(AbstractSession session, boolean invalidate)
-    {
-        // Remove session from context and global maps
-        boolean removed = false;
-
-        synchronized (this)
-        {
-            //take this session out of the map of sessions for this context
-            if (getSession(session.getClusterId()) != null)
-            {
-                removed = true;
-                removeSession(session.getClusterId());
-            }
-        }
-
-        if (removed)
-        {
-            // Remove session from all context and global id maps
-            _sessionIdManager.removeSession(session);
-
-            if (invalidate)
-                _sessionIdManager.invalidateAll(session.getClusterId());
-
-            if (invalidate && !_sessionListeners.isEmpty())
-            {
-                HttpSessionEvent event=new HttpSessionEvent(session);
-                for (HttpSessionListener l : _sessionListeners)
-                    l.sessionDestroyed(event);
-            }
-            if (!invalidate)
-            {
-                session.willPassivate();
-            }
-        }
-    }
-
-
-    /**
-     * Expire any Sessions we have in memory matching the list of
-     * expired Session ids.
-     *
-     * @param sessionIds
-     */
-    protected void expire (List<?> sessionIds)
-    {
-        //don't attempt to scavenge if we are shutting down
-        if (isStopping() || isStopped())
-            return;
-
-        //Remove any sessions we already have in memory that match the ids
-        Thread thread=Thread.currentThread();
-        ClassLoader old_loader=thread.getContextClassLoader();
-        ListIterator<?> itor = sessionIds.listIterator();
-
-        try
-        {
-            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 != null)
-                {
-                    session.timeout();
-                    itor.remove();
-                }
-                else
-                {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("Unrecognized session id="+sessionId);
-                }
-            }
-        }
-        catch (Throwable t)
-        {
-            LOG.warn("Problem expiring sessions", t);
-        }
-        finally
-        {
-            thread.setContextClassLoader(old_loader);
-        }
-    }
-
-
-    /**
-     * Load a session from the database
-     * @param id
-     * @return the session data that was loaded
-     * @throws Exception
-     */
-    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()
-        {
-            @SuppressWarnings("unchecked")
-            public void run()
-            {
-                Session session = null;
-                Connection connection=null;
-                PreparedStatement statement = null;
-                try
-                {
-                    connection = getConnection();
-                    statement = _jdbcSessionIdMgr._dbAdaptor.getLoadStatement(connection, id, canonicalContextPath, vhost);
-                    ResultSet result = statement.executeQuery();
-                    if (result.next())
-                    {                    
-                        session = new Session(id, result.getString(_jdbcSessionIdMgr._sessionTableRowId), result.getLong("createTime"), result.getLong("accessTime"));
-                        session.setCookieSet(result.getLong("cookieTime"));
-                        session.setLastAccessedTime(result.getLong("lastAccessTime"));
-                        session.setLastNode(result.getString("lastNode"));
-                        session.setLastSaved(result.getLong("lastSavedTime"));
-                        session.setExpiryTime(result.getLong("expiryTime"));
-                        session.setCanonicalContext(result.getString("contextPath"));
-                        session.setVirtualHost(result.getString("virtualHost"));
-                                           
-                        InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map");
-                        ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is);
-                        Object o = ois.readObject();
-                        session.addAttributes((Map<String,Object>)o);
-                        ois.close();
-
-                        if (LOG.isDebugEnabled())
-                            LOG.debug("LOADED session "+session);
-                    }
-                    _reference.set(session);
-                }
-                catch (Exception e)
-                {
-                    _exception.set(e);
-                }
-                finally
-                {
-                    if (statement!=null)
-                    {
-                        try { statement.close(); }
-                        catch(Exception e) { LOG.warn(e); }
-                    }
-
-                    if (connection!=null)
-                    {
-                        try { connection.close();}
-                        catch(Exception e) { LOG.warn(e); }
-                    }
-                }
-            }
-        };
-
-        if (_context==null)
-            load.run();
-        else
-            _context.getContextHandler().handle(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 data
-     * @throws Exception
-     */
-    protected void storeSession (Session session)
-    throws Exception
-    {
-        if (session==null)
-            return;
-
-        //put into the database
-        Connection connection = getConnection();
-        PreparedStatement statement = null;
-        try
-        {
-            String rowId = calculateRowId(session);
-
-            long now = System.currentTimeMillis();
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_jdbcSessionIdMgr._insertSession);
-            statement.setString(1, rowId); //rowId
-            statement.setString(2, session.getId()); //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.getCookieSet());//time cookie was set
-            statement.setLong(10, now); //last saved time
-            statement.setLong(11, session.getExpiryTime());
-
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(session.getAttributeMap());
-            byte[] bytes = baos.toByteArray();
-
-            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-            statement.setBinaryStream(12, 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);
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection!=null)
-                connection.close();
-        }
-    }
-
-
-    /**
-     * Update data on an existing persisted session.
-     *
-     * @param data the session
-     * @throws Exception
-     */
-    protected void updateSession (Session data)
-    throws Exception
-    {
-        if (data==null)
-            return;
-
-        Connection connection = getConnection();
-        PreparedStatement statement = null;
-        try
-        {
-            long now = System.currentTimeMillis();
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSession);
-            statement.setString(1, getSessionIdManager().getWorkerName());//my node id
-            statement.setLong(2, data.getAccessed());//accessTime
-            statement.setLong(3, data.getLastAccessedTime()); //lastAccessTime
-            statement.setLong(4, now); //last saved time
-            statement.setLong(5, data.getExpiryTime());
-
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            ObjectOutputStream oos = new ObjectOutputStream(baos);
-            oos.writeObject(data.getAttributeMap());
-            byte[] bytes = baos.toByteArray();
-            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-            statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob
-            statement.setString(7, data.getRowId()); //rowId
-            statement.executeUpdate();
-
-            data.setLastSaved(now);
-            if (LOG.isDebugEnabled())
-                LOG.debug("Updated session "+data);
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection!=null)
-                connection.close();
-        }
-    }
-
-
-    /**
-     * Update the node on which the session was last seen to be my node.
-     *
-     * @param data the session
-     * @throws Exception
-     */
-    protected void updateSessionNode (Session data)
-    throws Exception
-    {
-        String nodeId = getSessionIdManager().getWorkerName();
-        Connection connection = getConnection();
-        PreparedStatement statement = null;
-        try
-        {
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionNode);
-            statement.setString(1, nodeId);
-            statement.setString(2, data.getRowId());
-            statement.executeUpdate();
-            statement.close();
-            if (LOG.isDebugEnabled())
-                LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId);
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection!=null)
-                connection.close();
-        }
-    }
-
-    /**
-     * Persist the time the session was last accessed.
-     *
-     * @param data the session
-     * @throws Exception
-     */
-    private void updateSessionAccessTime (Session data)
-    throws Exception
-    {
-        Connection connection = getConnection();
-        PreparedStatement statement = null;
-        try
-        {
-            long now = System.currentTimeMillis();
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionAccessTime);
-            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.setString(6, data.getRowId());
-            statement.executeUpdate();
-            data.setLastSaved(now);
-            statement.close();
-            if (LOG.isDebugEnabled())
-                LOG.debug("Updated access time session id="+data.getId());
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection!=null)
-                connection.close();
-        }
-    }
-
-
-
-
-    /**
-     * Delete a session from the database. Should only be called
-     * when the session has been invalidated.
-     *
-     * @param data
-     * @throws Exception
-     */
-    protected void deleteSession (Session data)
-    throws Exception
-    {
-        Connection connection = getConnection();
-        PreparedStatement statement = null;
-        try
-        {
-            connection.setAutoCommit(true);
-            statement = connection.prepareStatement(_jdbcSessionIdMgr._deleteSession);
-            statement.setString(1, data.getRowId());
-            statement.executeUpdate();
-            if (LOG.isDebugEnabled())
-                LOG.debug("Deleted Session "+data);
-        }
-        finally
-        {
-            if (statement!=null)
-            {
-                try { statement.close(); }
-                catch(Exception e) { LOG.warn(e); }
-            }
-
-            if (connection!=null)
-                connection.close();
-        }
-    }
-
-
-
-    /**
-     * 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
-     * @return
-     */
-    private String calculateRowId (Session data)
-    {
-        String rowId = canonicalize(_context.getContextPath());
-        rowId = rowId + "_" + getVirtualHost(_context);
-        rowId = rowId+"_"+data.getId();
-        return rowId;
-    }
-
-    /**
-     * 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
-     * @return
-     */
-    private static String canonicalize (String path)
-    {
-        if (path==null)
-            return "";
-
-        return path.replace('/', '_').replace('.','_').replace('\\','_');
-    }
-}
diff -r b3176fd168bf -r 09d518d313b7 src/org/eclipse/jetty/server/session/SessionHandler.java
--- a/src/org/eclipse/jetty/server/session/SessionHandler.java	Thu Sep 08 16:13:27 2016 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,346 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2014 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.util.EnumSet;
-import java.util.EventListener;
-import javax.servlet.DispatcherType;
-import javax.servlet.ServletException;
-import javax.servlet.SessionTrackingMode;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.eclipse.jetty.http.HttpCookie;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.SessionManager;
-import org.eclipse.jetty.server.handler.ScopedHandler;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
-
-/* ------------------------------------------------------------ */
-/**
- * SessionHandler.
- */
-public class SessionHandler extends ScopedHandler
-{
-    final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
-
-    public final static EnumSet<SessionTrackingMode> DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE,SessionTrackingMode.URL);
-
-    /* -------------------------------------------------------------- */
-    private SessionManager _sessionManager;
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Constructor. Construct a SessionHandler witha a HashSessionManager with a standard java.util.Random generator is created.
-     */
-    public SessionHandler()
-    {
-        this(new HashSessionManager());
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param manager
-     *            The session manager
-     */
-    public SessionHandler(SessionManager manager)
-    {
-        setSessionManager(manager);
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @return Returns the sessionManager.
-     */
-    public SessionManager getSessionManager()
-    {
-        return _sessionManager;
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param sessionManager
-     *            The sessionManager to set.
-     */
-    public void setSessionManager(SessionManager sessionManager)
-    {
-        if (isStarted())
-            throw new IllegalStateException();
-        SessionManager old_session_manager = _sessionManager;
-
-        if (getServer() != null)
-            getServer().getContainer().update(this,old_session_manager,sessionManager,"sessionManager",true);
-
-        if (sessionManager != null)
-            sessionManager.setSessionHandler(this);
-
-        _sessionManager = sessionManager;
-
-        if (old_session_manager != null)
-            old_session_manager.setSessionHandler(null);
-    }
-
-    /* ------------------------------------------------------------ */
-    @Override
-    public void setServer(Server server)
-    {
-        Server old_server = getServer();
-        if (old_server != null && old_server != server)
-            old_server.getContainer().update(this,_sessionManager,null,"sessionManager",true);
-        super.setServer(server);
-        if (server != null && server != old_server)
-            server.getContainer().update(this,null,_sessionManager,"sessionManager",true);
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see org.eclipse.thread.AbstractLifeCycle#doStart()
-     */
-    @Override
-    protected void doStart() throws Exception
-    {
-        _sessionManager.start();
-        super.doStart();
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see org.eclipse.thread.AbstractLifeCycle#doStop()
-     */
-    @Override
-    protected void doStop() throws Exception
-    {
-        // Destroy sessions before destroying servlets/filters see JETTY-1266
-        _sessionManager.stop();
-        super.doStop();
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
-     */
-    @Override
-    public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
-    {
-        SessionManager old_session_manager = null;
-        HttpSession old_session = null;
-        HttpSession access = null;
-        try
-        {
-            old_session_manager = baseRequest.getSessionManager();
-            old_session = baseRequest.getSession(false);
-
-            if (old_session_manager != _sessionManager)
-            {
-                // new session context
-                baseRequest.setSessionManager(_sessionManager);
-                baseRequest.setSession(null);
-                checkRequestedSessionId(baseRequest,request);
-            }
-
-            // access any existing session
-            HttpSession session = null;
-            if (_sessionManager != null)
-            {
-                session = baseRequest.getSession(false);
-                if (session != null)
-                {
-                    if (session != old_session)
-                    {
-                        access = session;
-                        HttpCookie cookie = _sessionManager.access(session,request.isSecure());
-                        if (cookie != null) // Handle changed ID or max-age refresh
-                            baseRequest.getResponse().addCookie(cookie);
-                    }
-                }
-                else
-                {
-                    session = baseRequest.recoverNewSession(_sessionManager);
-                    if (session != null)
-                        baseRequest.setSession(session);
-                }
-            }
-
-            if (LOG.isDebugEnabled())
-            {
-                LOG.debug("sessionManager=" + _sessionManager);
-                LOG.debug("session=" + session);
-            }
-
-            // start manual inline of nextScope(target,baseRequest,request,response);
-            if (_nextScope != null)
-                _nextScope.doScope(target,baseRequest,request,response);
-            else if (_outerScope != null)
-                _outerScope.doHandle(target,baseRequest,request,response);
-            else
-                doHandle(target,baseRequest,request,response);
-            // end manual inline (pathentic attempt to reduce stack depth)
-
-        }
-        finally
-        {
-            if (access != null)
-                _sessionManager.complete(access);
-
-            HttpSession session = baseRequest.getSession(false);
-            if (session != null && old_session == null && session != access)
-                _sessionManager.complete(session);
-
-            if (old_session_manager != null && old_session_manager != _sessionManager)
-            {
-                baseRequest.setSessionManager(old_session_manager);
-                baseRequest.setSession(old_session);
-            }
-        }
-    }
-
-    /* ------------------------------------------------------------ */
-    /*
-     * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
-     */
-    @Override
-    public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
-    {
-        // start manual inline of nextHandle(target,baseRequest,request,response);
-        if (never())
-            nextHandle(target,baseRequest,request,response);
-        else if (_nextScope != null && _nextScope == _handler)
-            _nextScope.doHandle(target,baseRequest,request,response);
-        else if (_handler != null)
-            _handler.handle(target,baseRequest,request,response);
-        // end manual inline
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * Look for a requested session ID in cookies and URI parameters
-     *
-     * @param baseRequest
-     * @param request
-     */
-    protected void checkRequestedSessionId(Request baseRequest, HttpServletRequest request)
-    {
-        String requested_session_id = request.getRequestedSessionId();
-
-        SessionManager sessionManager = getSessionManager();
-
-        if (requested_session_id != null && sessionManager != null)
-        {
-            HttpSession session = sessionManager.getHttpSession(requested_session_id);
-            if (session != null && sessionManager.isValid(session))
-                baseRequest.setSession(session);
-            return;
-        }
-        else if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType()))
-            return;
-
-        boolean requested_session_id_from_cookie = false;
-        HttpSession session = null;
-
-        // Look for session id cookie
-        if (_sessionManager.isUsingCookies())
-        {
-            Cookie[] cookies = request.getCookies();
-            if (cookies != null && cookies.length > 0)
-            {
-                final String sessionCookie=sessionManager.getSessionCookieConfig().getName();
-                for (int i = 0; i < cookies.length; i++)
-                {
-                    if (sessionCookie.equalsIgnoreCase(cookies[i].getName()))
-                    {
-                        requested_session_id = cookies[i].getValue();
-                        requested_session_id_from_cookie = true;
-
-                        LOG.debug("Got Session ID {} from cookie",requested_session_id);
-
-                        if (requested_session_id != null)
-                        {
-                            session = sessionManager.getHttpSession(requested_session_id);
-
-                            if (session != null && sessionManager.isValid(session))
-                            {
-                                break;
-                            }
-                        }
-                        else
-                        {
-                            LOG.warn("null session id from cookie");
-                        }
-                    }
-                }
-            }
-        }
-
-        if (requested_session_id == null || session == null)
-        {
-            String uri = request.getRequestURI();
-
-            String prefix = sessionManager.getSessionIdPathParameterNamePrefix();
-            if (prefix != null)
-            {
-                int s = uri.indexOf(prefix);
-                if (s >= 0)
-                {
-                    s += prefix.length();
-                    int i = s;
-                    while (i < uri.length())
-                    {
-                        char c = uri.charAt(i);
-                        if (c == ';' || c == '#' || c == '?' || c == '/')
-                            break;
-                        i++;
-                    }
-
-                    requested_session_id = uri.substring(s,i);
-                    requested_session_id_from_cookie = false;
-                    session = sessionManager.getHttpSession(requested_session_id);
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("Got Session ID {} from URL",requested_session_id);
-                }
-            }
-        }
-
-        baseRequest.setRequestedSessionId(requested_session_id);
-        baseRequest.setRequestedSessionIdFromCookie(requested_session_id != null && requested_session_id_from_cookie);
-        if (session != null && sessionManager.isValid(session))
-            baseRequest.setSession(session);
-    }
-
-    /* ------------------------------------------------------------ */
-    /**
-     * @param listener
-     */
-    public void addEventListener(EventListener listener)
-    {
-        if (_sessionManager != null)
-            _sessionManager.addEventListener(listener);
-    }
-
-    /* ------------------------------------------------------------ */
-    public void clearEventListeners()
-    {
-        if (_sessionManager != null)
-            _sessionManager.clearEventListeners();
-    }
-}